1 工具介绍
JDB
这款工具集成在 JDK
中,在安装 Java
时已经自带,不需要特殊安装。它是一款基于文本和命令行的调试工具,现在很多的 Java IDE
中都提供了完善的断点调试功能,很方便,这也导致很多的开发人员认为这很原始,既然有更好的调试工具选择,很多人都放弃使用这款工具。
2 工具使用
JDB
基本用法如下代码所示。
jdb <options> <class> <arguments>
#<class> 是要开始调试的类的名称
#<arguments> 是传递到 <class> 的 main() 方法的参数
options
其中的 options
包括用于以有效的方式调试Java
程序的命令行选项。JDB
启动器接受所有选项(例如 -D
,-classpath
和 -X
)和一些其他高级选项,如(-attach
,-listen
,-launch
等)。
-help 输出帮助并退出
-sourcepath <由 ":" 分隔的目录>
要在其中查找源文件的目录
-attach <address> 使用标准连接器附加到指定地址处正在运行的 VM
-listen <address> 等待正在运行的 VM 使用标准连接器在指定地址处连接
-listenany 等待正在运行的 VM 使用标准连接器在任何可用地址处连接
-launch 立即启动 VM 而不是等待 'run' 命令
-listconnectors 列出此 VM 中的可用连接器
-connect <connector-name>:<name1>=<value1>,...
使用所列参数值通过指定的连接器连接到目标 VM
-dbgtrace [flags] 输出信息供调试jdb
-tclient 在 HotSpot(TM) 客户机编译器中运行应用程序
-tserver 在 HotSpot(TM) 服务器编译器中运行应用程序
转发到被调试进程的选项:
-v -verbose[:class|gc|jni] 启用详细模式
-D<name>=<value> 设置系统属性
-classpath <由 ":" 分隔的目录>
列出要在其中查找类的目录
-X<option> 非标准目标 VM 选项
3 调试
断点
首先我们需要编写一个 Java
代码文件,然后使用 Javac
命令进行编译产生 class
文件。然后使用 JDB
工具进行挂载运行。
Javac -g XXX.Java # 使用-g参数在编译时会帮你生成局部变量表、指令和代码行偏移量映射等信息
然后我们可以使用stop
指令设置断点位置。比如我们在XXX
类的main()
方法上设置断点。
stopin XXX.main # 不用加括号
stop
指令的基本用法如下:
# 在特定行号上设置断点
stop at <class id>:<line>
# 在特定方法上设置断点
stop in <class id>.<method>
设置完断点之后使用 run
指令将程序运行起来,程序将会运行到前文指定断点处之后停下,输出相关信息。如果想要继续执行可以使用 cont
、 step
和 step up
指令,其中 cont
是直接运行到下一个断点处;step
指令是只运行下一条语句并停止;step up
指令是运行到该方法退出并停止。
4 调试 jar
上文简述了一下本地调试 class
的基本命令,但是使用上述方法是无法对 jar
文件进行调试的。一般我们运行 jar
文件时直接使用 Java -jar xxx.jar
即可,但是如果想使用 jdb
工具对其进行调试,需要添加额外的命令行参数,与此同时,在启用 JDB
时也需要添加额外命令行参数。
Java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar xxx.jar
jdb -attach <ip>:36888#连接到JVM
这种方式同时也用来远程调试 Java
文件。
5 Connector
通过** jdb -listconnectors** 命令可以查看本机JDK支持的连接器;
注意:通过Connector不需要做任何额外配置,但调速器不能对进程做任何修改,也就是说类似进入只读模式;
6、调试包
6.1 调试本地进程
jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=44159
6.2 调试远程进程
- 启动SA Debug Server
jsadebugd <pid> [server-id]
如果启动多个debug server,可以配置server-id;
- 连接到远程SA Debug Server
jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=machine1
注:machine1为机器名或IP
6.3 调试本机CoreDump
jdb -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:core= <core file>,javaExecutable=$JAVA_HOME/bin/java
6.4 调试远程CoreDump
- 启动SA Debug Server
jsadebugd $JAVA_HOME/bin/java core.20441
- 连接到远程SA Debug Server
jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=machine1
注:machine1为机器名或IP
7 其他
除去上文提到的几种指令,jdb
工具还提供了很多操作指令,例如跟踪方法、获取指定错误类型、对象锁消息、操作表达式、查看变量等。
print <expr> -- 输出表达式的值
dump <expr> -- 输出所有对象信息
eval <expr> -- 对表达式求值 (与 print 相同)
set <lvalue> = <expr> -- 向字段/变量/数组元素分配新值
locals -- 输出当前堆栈帧中的所有本地变量
watch [access|all] <class id>.<field name> -- 监视对字段的访问/修改
unwatch [access|all] <class id>.<field name> -- 停止监视对字段的访问/修改
trace [go] methods [thread] -- 跟踪方法进入和退出。
trace [go] method exit | exits [thread] -- 跟踪当前方法的退出, 或者所有方法的退出
clear <class id>.<method>[(argument_type,...)] -- 清除方法中的断点
clear <class id>:<line> -- 清除行中的断点
clear -- 列出断点
常用命令
jdb支持的命令可以通过help查看,常见的命令包括:
-
添加断点
stop at com.test.MyClass:22 stop in java.lang.String.length stop in com.test.MyClass.<init>#构造函数 stop in com.test.MyClass.<clinit>#静态代码块
-
查看线程
threads #查看所有线程 thread <id> #查看单个线程 where #查看线程堆栈 pop #当前帧出栈, 且打印当前帧
-
单步调试
step #执行当前行 step up #一直执行, 直到当前方法返回到其调用方 stepi #执行当前指令 next #步进一行 (调用) cont #从断点处继续执行
-
查看变量
print <expr> #输出表达式的值 dump <expr> #输出所有对象信息 eval <expr> #对表达式求值 (与 print 相同) set <lvalue> = <expr> #向字段/变量/数组元素分配新值 locals #输出当前堆栈帧中的所有本地变量
-
其他
list [line number|method] -- 输出源代码 use (或 sourcepath) [source file path] #显示或更改源路径(目录)
转: