JAVA 调试, JPDA, Java Debug

JAVA 调试, JPDA, Java Debug JPDA 三层:JDI(调试器 Java API)→ JDWP(线协议)→ JVMTI(JVM native)。JVMTI 专文见 JVMTI。开发期改已加载类(HotSwap)走本体系,与 BTrace attach 观测不是同一路;热替换总览见 开发期热替换。 远程调试 远程调试分为主动连接调试,和被动连接调试。这里以Eclipse为例。 主动连接调试:服务端配置监控端口,本地IDE连接远程监听端口进行调试,一般调试问题用这种方式。 被动连接调试:本地IDE监听某端口,等待远程连接本地端口。一般用于远程服务启动不了,启动时连接到本地调试分析。 主动连接调试 首先需要远程服务配置启动脚本: JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005" 如果是启动jar包,指令: java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -jar test.jar JAVA 自身支持调试功能,并提供了一个简单的调试工具 - JDB, 类似于功能强大的 GDB,JDB 也是一个字符界面的调试环境,并支持设置断点,支持线程线级的调试。 JAVA的调试方法如下: 首先设置JVM,并设置参数,使之工作在 DEBUG 模式下,加入参数: -Xdebug -Xrunjdwp,transport=dt_socket,server=y,address=5432,suspend=n,onthrow=java.io.IOException,launch=/sbin/echo -Xdebug: 通知 JVM 工作在 DEBUG 模式下 -Xrunjdwp 是通知 JVM 使用 (java debug wire protocol) 来运行调试环境。该参数提供了一系列的调试选项: transport 指定调试数据的传送方式,dt_socket 是指用 SOCKET 模式,另有 dt_shmem 指用共享内存方式,其中,dt_shmem 只适用于 Windows 平台。 server 参数是指是否支持在 server 模式的 JVM 中. onthrow 当产生该类型的 Exception 时,JVM 就会中断下来,进行调式。(可选参数) launch 当JVM被中断下来时,执行的可执行程序。(可选参数) suspend: y/n 指明,是否在调试客户端建立起来后,再执行JVM。 onuncaught (=y或n) 指明出现 uncaught exception 后, 是否中断JVM的执行. address 端口 启动调试工具。 最简单的调试工具就是上面提到的JDB,以上述调试用JVM为例,可以用下面的命运行启动JDB: ...

Created 7076-06-07 · Updated 9096-10-09 · 8 min · 1625 words · -

开发期热替换(HotSwap、DCEVM、HotSwapAgent)

背景 开发时希望改 Java 代码后 少重启 就能看到效果。这与生产上 BTrace attach 观测 不是同一条路。本文归纳 HotSwap 及相关工具,并说明各自边界。 字节码织入与 redefine 机制见 java-asm;调试协议见 JPDA、JVMTI。 HotSwap 是什么 HotSwap(热替换)泛指:不重启整个 JVM,把 已在内存中的类 换成新字节码。 HotSpot 自带 的热替换能力很窄(通过 调试器 触发,底层 JVMTI / redefine): 常见成功:改 已有方法的方法体 常见失败:新增方法/字段、改签名、改继承、新 import 等 因此 IDE 在 Debug 下保存后提示 “Hot swap” 成功或失败,依赖的是 JPDA → JDWP → JVMTI,不是 Attach API 加载 BTrace agent 那条栈。 开发期 HotSwap(典型) IDE 编译 .class → JDWP 命令 → JVM redefine 已加载类 生产期 BTrace(对比) loadAgent → Instrumentation + ASM retransform → 插探针(观测) 几种开发期方案 方案 怎么做 能力边界 IDE HotSwap Debug + JPDA 方法体为主,标准 HotSpot 最严 JRebel 商业 agent 类加载/字节码策略更激进,需授权 DCEVM 替换/并行使用 修改版 HotSpot(-XXaltjvm=dcevm) 放宽 redefine:可加删方法/字段等 HotSwapAgent -javaagent:hotswapagent.jar + 常配合 DCEVM 用 Javassist 改字节码;插件重载 Spring/Hibernate 等配置 Spring Boot DevTools 双 ClassLoader 快速 Restart 重建 Spring 上下文,不是 JVM 级 HotSwap Spring DevTools 细节见 Spring Boot DevTools。 ...

Created 17176-12-17 · Updated 31316-05-31 · 2 min · 224 words · -

JVMTI(Java 虚拟机工具接口)

背景 调试器断点、IDE 热替换、jcmd 部分能力、Attach API 的 loadAgentLibrary、native agent,底层都依赖 JVM 提供的 native 级 工具接口。在 HotSpot/OpenJDK 上,这一层主要是 JVMTI。 JVMTI 是什么 JVMTI(Java Virtual Machine Tool Interface)是 JVM 实现的 C 语言 native 接口(jvmti.h),用于: 调试:断点、单步、查看栈与局部变量 分析:采样、分配追踪 类与字节码:监听类加载、重定义已加载类(与 IDE HotSwap 相关) Agent:native agent 在 Agent_OnLoad 里通过 JavaVM::GetEnv 拿到 jvmtiEnv 它 不是 Java 应用直接 import 的包;Java 侧看到的是更高层的封装。 前身(已淘汰) 用途 JVMDI 调试 JVMPI 性能分析 JDK 5+ 由 JVMTI 统一替代(见 JPDA 文中的历史说明)。 与 JPDA、Instrumentation 的关系 IDE / jdb(调试器) ↓ JDI(Java API) ↓ JDWP(线协议,如 dt_socket) ↓ JVMTI Agent(如 jdwp.so)→ JVMTI 调用 ↓ HotSpot JVM java.lang.instrument(Java Agent,premain/agentmain) ↓ JVM 内部同样依赖 JVMTI 等 native 能力实现 redefine/retransform 接口 语言 典型用途 JVMTI C / native 调试器后端、profiler、native agent JPDA(JDI + JDWP + JVMTI) 调试体系 Eclipse/IDEA 远程调试、JDB java.lang.instrument Java BTrace、Arthas、-javaagent、部分 APM 三者都落在 同一 JVM 进程 里,但入口不同:写 Java 诊断 agent 用 instrument + Attach;写调试器走 JPDA;写 native 库 agent 用 JVMTI + loadAgentLibrary。 ...

Created 31316-05-31 · Updated 31316-05-31 · 1 min · 195 words · -