java jdb 命令行调试程序

时间:2024-11-12 13:04:50


日常的可以远程debug程序,线上程序查看线程堆栈和日志寻找线索。还不够的话可以使用jdb进行命令行debug程序。


(1)修改java启动脚本,把远程调试端口打开

JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"


(2)程序运行起来

(3)attach jdb到程序上,在程序所在机器上运行 下面的脚本

$JAVA_HOME$/bin/jdb -attach 127.0.0.1:8787


如果没有设置jdwp,会失败,显示下面的信息:


如果成功,会显示下面的信息


main是主函数入口

(4)指定断点,运行

在这个类的74行指定断点,使用stop at 语句,后面跟着类的全路径。冒号分隔,后面是行号。

stop at :74
回车,后在看到提示符main[1] , 输入 run,回车;

看到程序被断在line=74行的地方,这时对照源代码,进行调试。

next是执行下一步,相当于F6


(5)要查看局部变量,输入locals。


step 表示进入方法,相当于eclipse的F5。

(6)使用dump查看对象的值


(7)内部类如何stop断住?

jdb有两个语法,一个是stop at(行号)和stop in(方法)

stop in .Metaq3Extractor$

(8)线程运行的位置 where all,告诉所有线程的当前运行位置


(9)一个实际的例子:现象是多台机器(20)消费metaq的消息,但是有部分分区消费失败,有的机器可以成功消费,有的机器却消费失败。

metaq消费回调看到消费失败的日志,但是精卫没有打印任何异常,业务的apply方法内部打开了debug,如果收到消息也会打印到指定目录的文件,但是没有收到日志。只好jdb上调试了。



一步一步的,追到了异常抛出的地方。

()Ljava/lang/Class;

应该是包冲突,查看含有thrift的包

thrift-0.2. 和 libthrift-0.8.两个包,排除掉thrift-0.2.(因为dbsync使用的是 libthrift-0.8.),重启,发现没有效果,还是会抛出异常。在eclipse中查找这个类TProtocol (Ctl+Shift+T),发现hive-core这个包含有同名的类TProtocol,而且包路径也相同。其实系统没有用到hive,所以排除掉这hive-core包后,再部署启动,恢复正常~~~