使用JDB 远程调试Java程序
一. Tomcat服务
1.修改启动命令脚本
脚本路径: %TOMCAT_PATH%/bin/catalina.bat
在最上方加入下面配置
# address: 监听的端口, 可自行调整为未被占用的端口
SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
2.启动服务
# Windows Server
%TOMCAT_PATH%/bin/startup.bat
3. 使用JDB工具连接程序Debug监听端口
# localhost: 程序的IP地址, 按实际情况替换
# 8000: 程序Debug监听的端口, 按实际情况替换
# 非Windows平台可以使用 -attach localhost:8000 进行链接
%JAVA_HOME%/bin/jdb.exe -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000
连接成功示例
%JAVA_HOME%/bin/jdb.exe -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000 设置未捕获的java.lang.Throwable 设置延迟的未捕获的java.lang.Throwable 正在初始化jdb...
4. 设置源文件
# use: 显示或更改源路径
# 更改源码路径
use D:\tmp\src\main\java
# 查看当前源码路径
use
5. 设置行断点
# stop at <class>:<line>
# class: 要设置断点的类的全类名
# line: 要设置断点的行号
stop at cn.test.Main:10
6. 断点终端后操作
# 查看附近10行代码
list
# 输出当前堆栈帧中的所有本地变量
locals
# 打印变量和表达式结果
print obj
print 1+1
# 打印对象信息
dump obj
# 为字段/变量/数组元素指定新值
set str1 = "newStr"
# 查看当前断点
clear
# 清除断点
clear cn.test.Main:10
二. 独立可执行应用
三. JDB 命令参考
1. 启动命令
命令 | 说明 |
---|---|
stop in <class id>.<method>[(argument_type,...)] | 在方法中设置断点 |
stop at <class id>:<line> | 在行中设置断点 |
clear <class id>.<method>[(argument_type,...)] | 清除方法中的断点 |
clear <class id>:<line> | 清除行中的断点 |
clear | 列出断点 |
catch [uncaught/caught/all] <class id>/<class pattern> | 出现指定的异常错误时中断 |
ignore [uncaught/caught/all] <class id>/<class pattern> | 对于指定的异常错误, 取消 ‘catch’ |
connectors | 列出此 VM 中可用的连接器和传输 |
run [class [args]] | 开始执行应用程序的主类 |
threads [threadgroup] | 列出线程 |
thread <thread id> | 设置默认线程 |
suspend [thread id(s)] | 挂起线程 (默认值: all) |
resume [thread id(s)] | 恢复线程 (默认值: all) |
where [<thread id> / all] | 转储线程的堆栈 |
wherei [<thread id> / all] | 转储线程的堆栈, 以及 pc 信息 |
up [n frames] | 上移线程的堆栈 |
down [n frames] | 下移线程的堆栈 |
kill <thread id> <expr> | 终止具有给定的异常错误对象的线程 |
interrupt <thread id> | 中断线程 |
classes | 列出当前已知的类 |
class <class id> | 显示已命名类的详细资料 |
methods <class id> | 列出类的方法 |
fields <class id> | 列出类的字段 |
threadgroups | 列出线程组 |
threadgroup <name> | 设置当前线程组 |
!! | 重复执行最后一个命令 |
<n> <command> | 将命令重复执行 n 次 |
# <command> | 放弃 (无操作) |
help (或 ?) | 列出命令 |
version | 输出版本信息 |
exit (或 quit) | 退出调试器 |
3. 中断后命令
命令 | 说明 |
---|---|
cont | 从断点处继续执行 |
step | 执行当前行 |
step up | 一直执行, 直到当前方法返回到其调用方 |
stepi | 执行当前指令下一步。步进一行 (步过调用) |
untrace [methods] | 停止跟踪方法进入和/或退出 |
trace [go] methods [thread] | 跟踪方法进入和退出。除非指定 ‘go’, 否则挂起所有线程 |
trace [go] method exit / exits [thread] | 跟踪当前方法的退出, 或者所有方法的退出。除非指定 ‘go’, 否则挂起所有线程 |
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> | 停止监视对字段的访问/修改 |
list [line number/method] | 输出源代码 |
use (或 sourcepath) [source file path] | 显示或更改源路径 |
exclude [<class pattern>, ... / "none"] | 对于指定的类, 不报告步骤或方法事件 |
classpath | 从目标 VM 输出类路径信息 |
monitor <command> | 每次程序停止时执行命令 |
monitor | 列出监视器 |
unmonitor <monitor#> | 删除监视器 |
read <filename> | 读取并执行命令文件 |
lock <expr> | 输出对象的锁信息 |
threadlocks [thread id] | 输出线程的锁信息 |
pop | 通过当前帧出栈, 且包含当前帧 |
reenter | 与 pop 相同, 但重新进入当前帧 |
redefine <class id> <class file name> | 重新定义类的代码 |
disablegc <expr> | 禁止对象的垃圾收集 |
enablegc <expr> | 允许对象的垃圾收集 |
JDB使用参考链接