JDB是基于文本和命令行的调试工具(例如Sun JDB);虽然现在有一些很好的调试工具,然而 Java 调试器 (JDB) 提供了一些优点。最重要的是 JDB 可以免费获取并且是平台独立的。其缺点是它只有命令行格式,一些开发人员认为这很原始,而且难以使用。一些 IDE 已经将 GUI 界面构建到 JDB 调试 API(如 Jikes)。JDB 是 JDK 安装的一部分。它在 Java 2 平台中得到了增强。
命令列表
1. ** 命令列表 **
2. connectors - 列出此 VM 中可用的连接器和传送器 3.
4.run[类 [参数]] - 开始执行应用程序的主类 5.
6. threads [线程组] - 列出线程 7. thread <线程 ID> - 设置默认线程
8. suspend [线程 ID] - 暂停线程(默认为所有线程) 9. resume [线程 ID] - 恢复线程(默认为所有线程) 10. 其中 [<线程 ID> | all] - 转储线程的堆栈
11. 其中 [<线程 ID> | all] - 转储线程的堆栈,以及 pc 信息 12. up [n 帧] - 向上移动线程的堆栈 13. down [n 帧] - 向下移动线程的堆栈
14. kill <线程 ID> <表达式> - 中止具有给定的异常对象的线程 15. interrupt <线程 ID> - 中断线程 16.
17. print <表达式> - 输出表达式的值 18. dump <表达式> - 输出所有对象信息
19. eval <表达式> - 输出表达式的值(与 print 相同) 20. set
23. classes - 列出当前已知的类 24. class <类 ID> - 显示已命名的类的详细信息 25. methods <类 ID> - 列出类的方法 26. fields <类 ID> - 列出类的字段 27.
28. threadgroups - 列出线程组 29. threadgroup <名称> - 设置当前线程组 30.
31. stop in <类 ID>.<方法>[(参数类型,...)]
32. - 在方法中设置断点 33. stop at <类 ID>:<行> - 在行中设置断点 34. clear <类 ID>.<方法>[(参数类型,...)]
35. - 清除方法中的断点 36. clear <类 ID>:<行> - 清除行中的断点 37. clear - 列出断点 38. catch [uncaught|caught|all] <类 ID>|<类模式>
39. - 出现指定的异常时中断 40. ignore [uncaught|caught|all] <类 ID>|<类模式>
41. -- 对于指定的异常,取消 "catch" 42. watch [access|all] <类 ID>.<字段名>
43. - 监视对字段的访问/修改 44. unwatch [access|all] <类 ID>.<字段名>
45. - 停止监视对字段的访问/修改 46. trace methods [线程] - 跟踪方法输入和退出 47. untrace methods [线程] - 停止跟踪方法输入和退出 48. step - 执行当前行
49. step up - 执行到当前方法返回到其调用程序 50. stepi - 执行当前指令
51. next - 跳过一行(跨过调用) 52. cont - 从断点处继续执行 53.
54. list [line number|method] - 输出源代码 55. use(或 sourcepath) [源文件路径]
56. - 显示或更改源路径 57. exclude [<类模式>, ...| “无”]
58. - 对于指定的类,不报告步骤或方法事件 59. classpath - 从目标 VM 输出类路径信息 60.
61. monitor <命令> - 每次程序停止时执行命令 62. monitor - 列出监视器 63. unmonitor <监视器号> - 删除监视器
64. read <文件名> - 读取并执行命令文件 65.
66. lock <表达式> - 输出对象的锁信息 67. threadlocks [线程 ID] - 输出线程的锁信息 68.
69. pop - 弹出整个堆栈,且包含当前帧 70. reenter - 与 pop 相同,但重新输入当前帧 71. redefine <类 ID> <类文件名>
72. - 重新定义类的代码 73.
74. disablegc <表达式> - 禁止对象的垃圾收集 75. enablegc <表达式> - 允许对象的垃圾收集 76.
77. !! - 重复执行最后一个命令 78.
83. <类 ID>:带有软件包限定符的完整类名 84. <类模式>:带有前导或后缀通配符 (*) 的类名 85. <线程 ID>: "threads" 命令中报告的线程号 86. <表达式>:Java(TM) 编程语言表达式。 87. 支持大多数常见语法。 88.
89. 可以将启动命令置于 "jdb.ini" 或 ".jdbrc" 之中 90. (两者位于 user.home 或 user.dir 中
使用实例
17. args = instance of java.lang.String (id=323) 18. 局部变量: 19. a = 2 20. b = 3
21. main next 22. >
23. 已完成步骤: "thread=main", jvm.init.Example5.main(), line=8 bci=10 24.
25. main
首先我们写一个最简单的小程序,但是它包含了一些最基本的面向对象要素。 class test {
int a; int b;
test(int aa,int bb) {
a = aa; b = bb; }
int add()
{return a+b;} }
public class hehe
{
public static void main(String args[]) {
int a = 2; int b = 3; int c= a+b;
System.out.println(c); test kk=new test(1,2); System.out.println(kk.add()); } }
存为hehe.java后,用javac -g hehe.java进行编译。用参数g是为了产生各种调试信息,不用就无法调试。如果这里遇到问题,请参考Helloworld攻略。上面的程序是可以通过的,
可以直接用java hehe运行。下面结合该例子谈谈JDB的使用。
首先键入jdb hehe 如果出现下面信息,说明系统没有找到调试的类。此时可以用java -classpath . hehe命令解决。 C:\javasource> jdb hehe Initializing jdb... hehe not found >
如果出现一下信息,说明开始进行调试,一切正常。如果是调试Applet,则用 appletviewer -debug heheHTML命令进行调试 C:\javasource> jdb -classpath . hehe Initializing jdb... 0xb0:class(hehe) >
回想VC中的调试,应该是设置断点,然后再进行跟踪。
Java中也是一样。用stop命令进行断点设置。然后用 run 命令开始调试,运行程序到断点,这里断点是设置在 main 主函数中。 > stop at hehe:18
Breakpoint set at hehe:18 > run run hehe
running ... main
Breakpoint hit: hehe.main (hehe:18) main
此时可以用locals命令查看变量,用step命令进入下一条命令,也可以用单独一个stop命令来查看断点的设置情况。注意此时b还没有被赋值。 main locals Method arguments: Local variables: args = a = 2 main step
main
Breakpoint hit: hehe.main (hehe:19) main
当运行到System.out.println()函数时,会出现一下提示: main step main
Breakpoint hit: java.lang.ClassLoader.loadClass (ClassLoader:247)
这个是因为我们跟踪进去了println方法,我们一般没有必要这样做,此时可以用next跳过该方法进入到下一条一句。step的含义是进入函数跟踪,next是转入下一条语句执行。我们随时可以键入 locals 和 list 命令来查看变量值和当前运行的代码。下面箭头指到地方即为当前程序运行到的地方。 main NeXT main
Breakpoint hit: hehe.main (hehe:20) main list
16 {
17 int a = 2; 18 int b = 3; 19 int c= a+b;
20 => System.out.println(c); 21 test kk=new test(1,2); 22
System.out.println(kk.add());
23
24 } main
接下来的问题自然是如何查看对象。当程序运行到new命令处时,键入locals,可以看到 main step main
Breakpoint hit: test. (test:5) main list
1 class test 2 {
3 int a; 4 int b;
5 => test(int aa,int bb) 6 {
7 a = aa; 8 b = bb;
9 } main locals
Method arguments: Local variables:
this = test@64fd6722 aa = 1 bb = 2 main
可以看到此时显示的变量值是类test中构造函数中的变量值。this对象即为当前构造的对象。可以用dump命令进行查看。 main dump this this = (test)0x11a { int b = 0 int a = 0 }
也可以在main函数中用dump kk和print命令命令进行对象查看 main dump kk kk = (test)0x11a { int b = 2 int a = 1 }
main print kk kk = test@64fd6722 main print KKA kk.a = 1
main print kk.b kk.b = 2
最后键入cont命令,如果没有其他断点,程序就直接运行完毕退出。调试结束。 main cont 3
> Current thread "main " died. Execution continuing... >
hehe exited
上述操作中的断点都是设置在main函数中的,如果要设置在调用的类方法中,则要用 stop in yourclassname.functionname 命令来进行设置,比如说: > stop in test.add Breakpoint set in test.add > run run hehe running ... main 5
Breakpoint hit: test.add (test:11) main list
7 a = aa; 8 b = bb; 9 } 10 int add() 11 => {return a+b;} 12 }
13 public class hehe 14 {
15 public static void main(String args[]) main
这样的话,我们已经可以在程序中的几乎所有需要地方的地方进行断点设置并进行跟踪,查看变量。
JDB还有很多的调试手段,除了上面那些最常用的,其他很重要的还有clear清除断点,use设置源程序路径,memory显示当前内存使用状况,gc强制进行内存回收,!!重复上面的命令,thread设置当前线程,quit和exit退出jdb等,还有远程调试等内容,都很有用