java debug 原理简介
所属分类 jvm
浏览量 1776
JPDA(Java Platform Debugger Architecture)
JVM提供的一整套用于调试的工具和接口
JPDA可以分为三个部分
Java虚拟机工具接口(JVMTI)
Java调试线协议(JDWP) Java Debug Wire Protocol
Java调试接口(JDI)
调试者(debugger) 被调试者(Target JVM) 交互通道
JVMTI 可实现java调试器、java运行态测试以及分析工具等
可通过建立一个Agent的方式来使用JVMTI,通过设置回调函数,从java虚拟机上得到当前运行态信息,并执行相应的操作。
把Agent编译成一个动态链接库后,在java程序启动时加载她(增加启动参数agentlib/ agentpath)
java5之后支持运行时加载
以启动时加载为例,动态库加载后,虚拟机会寻找Agent的入口函数,定义如下:
在该函数中,虚拟机传入了一个JavaVM指针和命令行参数options,
由javaVM,可以获得jvmtiEnv指针,而通过 jvmtiEnv可以获取所有的JVMTI函数。
通过options可以做一些初始化操作 。
类定义之前能修改相关的字节码,从而使创建的class对象是修改之后的字节码内容,
可以写一个HandleClassFileLoadHook函数,然后在Agent_OnLoad函数里为jvmtiEventCallbacks设定对应的函数指针。
这样在接下来的虚拟机运行中,所有类的字节码文件在读取时都会进入HandleClassFileLoadHook函数,
可以在HandleClassFileLoadHook函数中进行修改字节码等操作。
JDWP(Java Debug Wire Protocol)定义了调试者和被调试者之间的通讯协议
被调试者(Target JVM)在启动时会加载一个Agent,该Agent里实现了各种方法,使用JVMTI函数,从而具备了调试功能,
调试者(Debugger)与被调试者(Target JVM)建立连接后,向其发送命令来获取其运行时的状态和控制java程序的运行,
发送命令和获取应答用的就是JDWP协议。
JDWP通讯可以分为两个阶段:握手和应答。
握手 Debugger发送字符串“JDWP-Handshake”到Target JVM,后者回复“JDWP-Handshake” 表示握手完成,通信正常。
握手完成后,Debugger就可以向Target JVM发送命令了。
和一般的连接方式类似,JDWP可以主动去连接debugger,也可以等待debugger的连接。
对于主动去连接debugger,需要调用Attach方法
对于JDWP等待debugger连接的方式,首先要调用其StartListening方法
该方法将使JDWP处于监听状态,随后调用Accept方法接收连接
Java调试接口(JDI)
JDI主要包含了一套针对客户端定义的接口,通过该接口,开发人员通过调试器(如eclipse调试器)来远程监控/控制后端虚拟机上被调试程序的运行,
eclipse的jdt.debug就是一个完整的JDI实现。
以调试模式启动JVM
-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
-Xrunjdwp JVM 加载 jdwp
transport=dt_socket 使用 Socket 传输
address 调试端口号
server=y 表示 JVM 作为服务器,建立 Socket
suspend=n 表示启动过程中,JVM 不会挂起去等待调试客户端连接
tomcat8.5启动过程远程调试
上一篇
下一篇
java代码获取所有jvm进程
ETF投资指南
银华日利(511880) vs 华宝添益(511990)
javaagent机制
javaagent两种加载方式及实例
Java8日期api使用