jdb-线上debug利器

2014-12-22 walter lee 更多博文 » 博客 » GitHub »

jdb

原文链接 http://www.xiangguo.li/coding/2014/12/22/jdb
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


{% include JB/setup %}

JDB

"jdb"命令

jdb是java的一个命令行debug工具,随JDK提供。语法如下:
jdb [options] main_class_name jdb [options] -attach

  • 这里"options"是指一系列的选项;
  • "main_class_name"是main函数所在的类名;
  • address是正在运行的JAVA进程

从上面可以看出,jdb有两种运行方式:

  1. 执行jdb命令启动java程序并开启debug会话
  2. 执行jdb命令连接到已经启动的java程序并开启debug会话

通常使用options -help 帮助 -verbose 输出更多的信息 -classpath classpath -Dproperty=value 定义新的系统属性 -launch 如果使用了launch表示jdb启动后即运行程序

执行jdb命令启动java程序并开启debug会话

编写JAVA程序 class Hello { public static void main(String[] a) { System.out.println("Hello world!");
} }

javac Hello.java

jdb Hello 正在初始化jdb... stop in Hello.main 正在延迟断点Hello.main。 将在加载类后设置。 run 运行Hello 设置未捕获的java.lang.Throwable 设置延迟的未捕获的java.lang.Throwable

VM 已启动: 设置延迟的断点Hello.main

断点命中: "线程=main", Hello.main(), 行=3 bci=0 3 System.out.println("Hello world!");

main[1] next

Hello world!

已完成的步骤: "线程=main", Hello.main(), 行=4 bci=8 4 }

main[1] cont

应用程序已退出

如果想在执行jdb命令时,自动运行程序,加上"- launch"选项: jdb -launch Hello 设置未捕获的java.lang.Throwable 设置延迟的未捕获的java.lang.Throwable 正在初始化jdb...

VM 已启动: 当前调用堆栈上没有帧

main[1] cont

Hello world!

应用程序已退出

执行jdb命令连接到已经启动的java程序并开启debug会话

本地

java -agentlib:jdwp=transport=dt_shmem,address=MyHello,server=y, suspend=y Hello jdb -attach MyHello

远程

监听

java -agentlib:jdwp=transport=dt_socket,address=localhost:8888,server=y,suspend=y Hello

连接

jdb -attach localhost:8888 或者 jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8888 设置未捕获的java.lang.Throwable 设置延迟的未捕获的java.lang.Throwable 正在初始化jdb...

VM 已启动: > 当前调用堆栈上没有帧

main[1] stop in Hello.main 正在延迟断点Hello.main。 将在加载类后设置。

main[1] run

设置延迟的断点Hello.main

断点命中: "线程=main", Hello.main(), 行=3 bci=0 3 System.out.println("Hello world!");

main[1] list 1 class Hello { 2 public static void main(String[] a) { 3 => System.out.println("Hello world!"); 4 } 5 } main[1] cont

应用程序已退出

常用命令

** 命令列表 ** connectors -- 列出此 VM 中可用的连接器和传输

run [class [args]] -- 开始执行应用程序的主类

threads [threadgroup] -- 列出线程 thread -- 设置默认线程 suspend [thread id(s)] -- 挂起线程 (默认值: all) resume [thread id(s)] -- 恢复线程 (默认值: all) where [ | all] -- 转储线程的堆栈 wherei [ | all]-- 转储线程的堆栈, 以及 pc 信息 up [n frames] -- 上移线程的堆栈 down [n frames] -- 下移线程的堆栈 kill -- 终止具有给定的异常错误对象的线程 interrupt -- 中断线程

print -- 输出表达式的值 dump -- 输出所有对象信息 eval -- 对表达式求值 (与 print 相同) set = -- 向字段/变量/数组元素分配新值 locals -- 输出当前堆栈帧中的所有本地变量

classes -- 列出当前已知的类 class -- 显示已命名类的详细资料 methods -- 列出类的方法 fields -- 列出类的字段

threadgroups -- 列出线程组 threadgroup -- 设置当前线程组

stop in .[(argument_type,...)] -- 在方法中设置断点 stop at : -- 在行中设置断点 clear .[(argument_type,...)] -- 清除方法中的断点 clear : -- 清除行中的断点 clear -- 列出断点 catch [uncaught|caught|all] | -- 出现指定的异常错误时中断 ignore [uncaught|caught|all] | -- 对于指定的异常错误, 取消 'catch' watch [access|all] . -- 监视对字段的访问/修改 unwatch [access|all] . -- 停止监视对字段的访问/修改 trace [go] methods [thread] -- 跟踪方法进入和退出。 -- 除非指定 'go', 否则挂起所有线程 trace [go] method exit | exits [thread] -- 跟踪当前方法的退出, 或者所有方法的退出 -- 除非指定 'go', 否则挂起所有线程 untrace [methods] -- 停止跟踪方法进入和/或退出 step -- 执行当前行 step up -- 一直执行, 直到当前方法返回到其调用方 stepi -- 执行当前指令 next -- 步进一行 (步过调用) cont -- 从断点处继续执行

list [line number|method] -- 输出源代码 use (或 sourcepath) [source file path] -- 显示或更改源路径 exclude [, ... | "none"] -- 对于指定的类, 不报告步骤或方法事件 classpath -- 从目标 VM 输出类路径信息

monitor -- 每次程序停止时执行命令 monitor -- 列出监视器 unmonitor -- 删除监视器 read -- 读取并执行命令文件

lock -- 输出对象的锁信息 threadlocks [thread id] -- 输出线程的锁信息

pop -- 通过当前帧出栈, 且包含当前帧 reenter -- 与 pop 相同, 但重新进入当前帧 redefine -- 重新定义类的代码

disablegc -- 禁止对象的垃圾收集 enablegc -- 允许对象的垃圾收集

!! -- 重复执行最后一个命令 -- 将命令重复执行 n 次

-- 放弃 (无操作)

help (或 ?) -- 列出命令 version -- 输出版本信息 exit (或 quit) -- 退出调试器

: 带有程序包限定符的完整类名 : 带有前导或尾随通配符 ('*') 的类名 : 'threads' 命令中报告的线程编号 : Java(TM) 编程语言表达式。 支持大多数常见语法。