2017-04-20 01:44:14 +0000   |     java tools jdb   |   Viewed times   |    

参考文献

《JDB的简单使用》

最简单的Demo

首先Demo被测试的代码是关于内部类的一段小练习,

package com.ciaoshen.thinkinjava.newchapter10;

class Exercise21 {
    private static interface PrivateInterface {
        public String foo();
        public static class NestedClassInInterface {
            public void callFoo(PrivateInterface instance) { System.out.println(instance.foo()); }
        }
    }
    private static class PrivateInterfaceImp implements PrivateInterface {
        public String foo() { return "Hello everyone! I am foo() method in PrivateInterfaceImp class!"; }
    }
    public static void main(String[] args) {
        PrivateInterfaceImp test = new PrivateInterfaceImp();
        PrivateInterface.NestedClassInInterface nested = new PrivateInterface.NestedClassInInterface();
        nested.callFoo(test);
    }
}

javac编译的时候带-g选项,表示编译时生成各种调试信息。

javac -g balabala…

比如我编译某个代码,

javac -g -cp ~/JavaCode/bin -sourcepath ~/JavaCode/src ~/JavaCode/src/com/ciaoshen/thinkinjava/newchapter10/Exercise21.java

jdb命令开始调试,第一个参数类名告诉调试器需要调试哪个.class类。

jdb option class-name arguments

接着之前的例子,开始调试,得到的交互式回答是一个>,这时候就可以输入下一步调试命令了,

jdb -classpath ~/JavaCode/bin com.ciaoshen.thinkinjava.newchapter10.Exercise21
Initializing jdb...
>

先设一个最简单的断点

设置断点

stop at class-name:line-number

运行加了断点的程序,

run

还是刚才的例子,

jdb com.ciaoshen.thinkinjava.newchapter10.Exercise21
Initializing jdb ...
> stop at com.ciaoshen.thinkinjava.newchapter10.Exercise21:18
Deferring breakpoint com.ciaoshen.thinkinjava.newchapter10.Exercise21:18.
It will be set after the class is loaded.
> run
run com.ciaoshen.thinkinjava.newchapter10.Exercise21
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint com.ciaoshen.thinkinjava.newchapter10.Exercise21:18

Breakpoint hit: "thread=main", com.ciaoshen.thinkinjava.newchapter10.Exercise21.main(), line=18 bci=9

main[1]

locals或命令查看本地变量

接着刚才的提示符输入locals

# ...
# balabala...
# ...
main[1] locals
Method arguments:
args = instance of java.lang.String[0] (id=428)
Local variables:
test = instance of com.ciaoshen.thinkinjava.newchapter10.Exercise21$PrivateInterfaceImp(id=429)
main[1]

step进入下一条命令

main[1] step
>
Step completed: "thread=main", com.ciaoshen.thinkinjava.newchapter10.Exercise21$PrivateInterface$NestedClassInInterface.<init>(), line=9 bci=0

main[1]

dump命令查看对象

随时都可以用locals查看局部变量,

main[1] locals
Method arguments:
args = instance of java.lang.String[0] (id=428)
Local variables:
test = instance of com.ciaoshen.thinkinjava.newchapter10.Exercise21$PrivateInterfaceImp(id=429)
nested = instance of com.ciaoshen.thinkinjava.newchapter10.Exercise21$PrivateInterface$NestedClassInInterface(id=431)
main[1] dump nested
 nested = {
}
main[1]

next转入下一条语句执行

这个可以用来跳过一些我们不想进入的步骤。

main[1] next
> Hello everyone! I am foo() method in PrivateInterfaceImp class!

list命令查看当前域的源代码

如果编译的时候带上了-sourcepath参数,还可以在调试的时候查看当前断点所处域的源代码。

cont命令退出调试

最后键入cont命令,如果没有其他断点,程序就直接运行完毕退出。调试结束。