Java Platform Debugger Architecture(JPDA:Java平台调试架构) 由Java虚拟机后端和调试平台前端组成,Java虚拟机提供了Java调试的功能,而调试平台通过调试交互协议向Java虚拟机请求服务以对在虚拟机中运行的程序进行调试(见下图)。
 
JPDA通过两个接口和协议来完成如上的说明,分别是JVMTI(Java虚拟机工具接口)、JDWP(Java调试连线协议)和JDI(Java调试接口)。JVMTI定义了虚拟机应该提供的调试服务,包括调试信息(Information譬如栈信息)、调试行为(Action譬如客户端设置一个断点)和通知(Notification譬如到达某个断点时通知客户端),该接口由虚拟机实现者提供实现,并结合在虚拟机中;JDWP定义调试服务和调试器之间的通信,包括定义调试信息格式和调试请求机制;而JDI在语言的高层次上定义了调试者可以使用的调试接口以能方便地与远程的调试服务进行交互,Java语言实现,调试器实现者可直接使用该接口访问虚拟机调试服务。
当虚拟机的调试服务运行时,虚拟机作为调试的服务提供端,监听一个连接,而调试器通过该连接与虚拟机进行交互。目前,Windows平台的JVM提供了两种方式的连接:共享内存和 Socket连接,共享内存的服务提供端和调试端只能位于同一台机,而Socket连接则支持不同异机调试,即远程调试。
在前面的篇章中,利用JPDA构建调试平台([a] http://www.blogcn.com/u2/38/21/ayufox/blog/36956440.html [/a])介绍了如何使用Eclipse构建测试平台,在本篇将详细介绍Sun HotSpot虚拟机提供启用详细参数设置。
1.启用调试服务
-Xdebug 启用调试
-Xrunjdwp:<sub-options> 加载JVM的JPDA参考实现库
2.Xrunjdwp子参数(sub-options)配置
Xrunjdwp子参数的配置格式如下
-Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]...
可以指定如下子参数
help  打印帮助信息并结束虚拟机运行
transport 连接方式,有dt_socket和dt_shmem两种,分别是Socket和共享内存
server 是否以服务器方式启,默认为n,即虚拟机作为调试客户端,一般将其指为y值,同时指定address参数,则虚拟机会监听到该address的调试请求,如果不指定address,则虚拟机使用address的默认值
address 连接地址,当指定server=n时,虚拟机在该地址上启动调试器,如果server=y,虚拟机监听该地址。如果使用socket连接,则address的默认值是一个随机端口
launch 与onthrow 和/或 onuncaught(见下)结合使用,当某个特定事件发生时,启动一个调试器进程进行实时调试
onthrow 当某个特定的异常抛出时才加载jdwp包,也就是当异常抛出时才启动调试服务
onuncaught 默认值为n,如果设为y,则当运行异常(RuntimeException)抛出时才加载jdwp包,即才启动调试服务
stdalloc 默认的,jdwp实现随机使用一个内存分配器来分配内存,如果指定值为y,则使用C运行库内存分配器分配内存
suspend 是否挂起,默认值为y,即主程序并不马上运行直到有调试请求到达,一般指定为n
3.例:
-Xrunjdwp:transport=dt_socket,server=y,address=8000
在8000端口监听Socket连接,挂起VM并且不加载运行主函数直到调试请求到达
-Xrunjdwp:transport=dt_shmem,server=y,suspend=n
选择一个可用的共享内存(因为没有指address)并监听该内存连接,同时加载运行主函数
-Xrunjdwp:transport=dt_socket,address=myhost:8000
连接到myhost:8000提供的调试服务(server=n,以调试客户端存在),挂起VM并且不加载运行主函数
-Xrunjdwp:transport=dt_shmem,address=mysharedmemory
通过共享内存的方式连接到调试服务,挂起VM并且不加载运行主函数
-Xrunjdwp:transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub
等待java.io.IOException被抛出,然后挂起VM并监听8000端口连接,在接到调试请求后以命令/usr/local/bin/debugstub dt_socket myhost:8000执行
-Xrunjdwp:transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe
等待一个RuntimeException被抛出,然后挂起VM并监听一个可用的共享内存,在接到调试请求后以命令d:\bin\debugstub.exe dt_shmem <address>执行,<address>是可用的共享内存我的BLOG:http://ayufox.blogcn.com/