Debug with jdb

简介: 原文地址: http://www.javaworld.com/article/2077445/testing-debugging/debug-with-jdb.html Q: How do you use jdb (included in the JDK 1.

原文地址: http://www.javaworld.com/article/2077445/testing-debugging/debug-with-jdb.html

Q: How do you use jdb (included in the JDK 1.2 package) effectively to debug Java programs?

I've tried many times, but I am successful only in loading a class file to jdb; I can't debug it. The help command isn't much use.

A: You ask an interesting question. To be honest, I've neverused jdb. I have always used the debugger provided by my IDE environment. So to answer your question I had to do a little research of my own.

It turns out that Sun considers jdb a proof of concept for the Java Debugger API. The Java Debugger API allows us to actually peek into the runtime and debug our code. The jdb is just one implementation of a debugger that uses the API. Compared to the visual debuggers with which I'm familiar (yes, I guess I'm a wimp), it's not the easiest debugger to use -- though it is similar to other command-line debuggers, such asgdb.

Anyhow, on to your question. Before attempting to debug your code, be sure to use the -g option while compiling your classes. This option tells the compiler to include debugging information in your class file.

Let's define a contrived class for testing:

publicclassTestMe{privateint int_value;privateString string_value;publicstaticvoid main(String[] args){TestMe testMe =newTestMe();
    testMe.setInt_value(1);
    testMe.setString_value("test");int integer = testMe.getInt_value();Stringstring= testMe.getString_value();String toString = testMe.toString();}publicTestMe(){}publicint getInt_value(){return int_value;}publicString getString_value(){return string_value;}publicvoid setInt_value(int value){
    int_value = value;}publicvoid setString_value(String value){
    string_value = value;}publicString toString(){return"String value: "+ string_value +" int value: "+ int_value;}}

Start the debugger:

> jdb TestMe

You should see:

>Initializing jdb...>0xaa:class

Let's take a look at some basic commands. In order to set breakpoints, we need to know the line numbers or the method names of the places where we would like to break. To obtain a list of methods, simply use the methods command:

> methods TestMevoid main(java.lang.String[])void()int getInt_value()
   java.lang.String getString_value()void setInt_value(int)void setString_value(java.lang.String)
   java.lang.String toString()

Setting a breakpoint is simple. Use the following syntax:

stop in.[<argument_type,...>]

Or:

stop at :

We should start debugging at the beginning of the main method:

> stop inTestMe.main
   Breakpointsetin javaworld.TestMe.main

Now that we have a breakpoint, we can begin execution. To run up to the breakpoint, simply use the run command:

> run
run javaworld.TestMe
running ...
main[1]Breakpoint hit: javaworld.TestMe.main (TestMe:10)

At this point, the debugger halts execution at the first line of the main method. Notice that the cursor has changed to reflect the method that we are currently in.

The list command will display the code at the breakpoint. An arrow indicates the spot where the debugger has halted execution.

main[1] list
6privateString string_value;78publicstaticvoid main(String[] args)9{10=>TestMe testMe =newTestMe();11             testMe.setInt_value(1);12             testMe.setString_value("test");1314int integer = testMe.getInt_value();
main[1]

Next, we'll want to step through a few lines of code and see what's changed:

main[1] step
main[1]Breakpoint hit: javaworld.TestMe.(TestMe:20)
main[1] locals
Method arguments:Local variables:this=String value:nullint value:0
main[1] list
1617String toString = testMe.toString();18}1920=>publicTestMe()21{22}2324publicint getInt_value()
main[1] step
main[1]Breakpoint hit: java.lang.Object.(Object:27)
main[1] list
Unable to find Object.java
main[1] step
main[1]Breakpoint hit: javaworld.TestMe.(TestMe:22)
main[1] list
18}1920publicTestMe()21{22=>}2324publicint getInt_value()25{26return int_value;
main[1] step
main[1]Breakpoint hit: javaworld.TestMe.main (TestMe:10)
main[1] list
6privateString string_value;78publicstaticvoid main(String[] args)9{10=>TestMe testMe =newTestMe();11             testMe.setInt_value(1);12             testMe.setString_value("test");1314int integer = testMe.getInt_value();
main[1] step
main[1]Breakpoint hit: javaworld.TestMe.main (TestMe:11)
main[1] list
78publicstaticvoid main(String[] args)9{10TestMe testMe =newTestMe();11=>     testMe.setInt_value(1);12             testMe.setString_value("test");1314int integer = testMe.getInt_value();15Stringstring= testMe.getString_value();
main[1] locals
Method arguments:Local variables:
  args =
  testMe =String value:nullint value:0

After each step, I called the list command to see where I was in the code. The return value from the command listed the line number, but somehow that didn't really help me very much.

As we step, we see that the main method is constructing a TestMe instance. Each step takes us through the constructor and finally back into the main method. The localscommand lists all of the local variables visible in the current stack. We see that at this point in the main method there are only two local variables: args and testMe.

By using step, we can get inside any of the methods to see what is going on. When we combine step with the locals command we can see our variables:

main[1] step
main[1]Breakpoint hit: javaworld.TestMe.setInt_value (TestMe:36)
main[1] list
32}3334publicvoid setInt_value(int value)35{36=>     int_value = value;37}3839publicvoid setString_value(String value)40{
main[1] locals
Method arguments:Local variables:
  value =1this=String value:nullint value:0

If we step one more time, we end up in the setInt_value()method. If we step two more times, the method will set the int_value member to 1 and return. (To check to see that the method set the value, use the locals command.)

Of course, when we step, we won't always want to trace into each method we encounter. Some method calls can nest very deeply. If we were forced to trace through an entire hierarchy, we might never finish. Luckily, jdb has a way to execute a method without tracing into that method: the next command.

jdb also provides a few other step commands. The stepi command executes the current instruction. In other words, the code at the => will execute but the current line will not advance to the next instruction. You can call stepi a million times, but the => displayed from the list command will not move.

jdb also provides the step up command. The step up call executes until the current method returns to its caller. Simply put, this stepper executes a method and nothing else. Take the following code segment as an example:

int integer = testMe.getInt_value();

If this is our current line and we run step up, the getInt_value() method will execute. However, that's all that will happen. The return value will not get set to integer.

jdb also allows us to set multiple breakpoints. To go from one breakpoint directly to the next, jdb provides the cont command.

Finally, there are times when we want to look at all the members of an instance or class. Luckily, jdb provides the dump and print commands:

main[1]dumpTestMeTestMe=0xa9:class(javaworld.TestMe){
    superclass =0x2:class(java.lang.Object)
    loader =(sun.misc.Launcher$AppClassLoader)0xaa}
main[1]printTestMeTestMe=0xa9:class(javaworld.TestMe)
main[1]dump testMe
testMe =(javaworld.TestMe)0xec{private java.lang.String string_value = test
    privateint int_value =1}
main[1]print testMe
testMe =String value: test int value:1
FEATURED RESOURCE
Presented by Dell Software

This paper highlights ten key takeaways from the most recent survey on the impact of Cloud on

LEARN MORE

When you run dump or print on a class, you get class information, which includes superclass and loader information. When you run dump and print on an instance, you get instance information, such as data members and their current values.

jdb also provides commands for getting down and dirty in the threads and stacks. However, these commands are really beyond the scope of a jdb intro.

One final point: you may ask, "How do you effectively usejdb?" The effectiveness of use will depend on your comfort level with jdb. When you first use jdb, the most important command is help. The help command lists each command and provides some basic information to help you get started. Once you have the help command mastered, you'll find yourself using the commands that set breakpoints, along with step and list. Any combination of those commands will allow you to get started using jdbstepliststeplist... should help you quickly locate code that is bombing out on you.

Learn more about this topic

目录
相关文章
|
设计模式 缓存 前端开发
通过Debug探索SpringMVC执行过程
对SpringMVC的理解 MVC:MVC是一种设计模式 MVC的原理图: M-Model 模型(完成业务逻辑:有javaBean构成,service+dao+entity) V-View 视图(做界面的展示 jsp,html……) C-Controller 控制器(接收请求—>调用模型—>根据结果派发页面) SpringMVC工作原理 springMVC是一个MVC的开源框架,springMVC=struts2+spring,springMVC就相当于是Struts2加上sring的整合,但是这里有一个疑惑就是,springMVC和spring是什么样的关系呢?这个在百度百科上有一个很好
99 0
intellij debug模式提示 : Method breakpoints may dramatically slow down debugging
最近在搞一个搭建一个项目 , 项目搭建完之后发现启动不了 , 一直都是正在加载中 并且提示Method breakpoints may dramatically slow down debugging,百度之后才知道是打了方法断点的原因 , 之前不小心打了一个断点
103 0
|
3月前
|
运维 NoSQL 安全
debug学习
debug学习
148 65
|
5月前
|
Shell Python
调试程序的故乡_调试程序_debug_next_下一步_list_pdb3
这篇 content 主要介绍了使用调试工具 pdb3 进行 Python 程序调试的基本步骤与技巧。首先,当遇到调试困境时,可以通过输入 `help` 查看可用命令。使用 `l` (list) 或 `ll` (list long) 分别查看当前行附近的代码或整个程序的代码。`l .` 和 `l n` 可以分别用于查看当前行周围的代码或从第 n 行开始的代码。通过 `next` (`n`) 命令逐步执行程序,观察每一步的结果。当到达程序末尾并再次使用 `next` 时,程序会重新开始执行。
28 2
|
6月前
深入理解Debug断点调试技巧
深入理解Debug断点调试技巧
135 1
|
7月前
|
网络架构
Debug系统调试
Debug系统调试
|
7月前
|
程序员
调试程序DEBUG的使用
调试程序DEBUG的使用
69 0
断点调试(debug)
断点调试(debug)
22225 0
|
Java
使用JDB Debugger
使用JDB Debugger
116 0
JDB Logger
JDB Logger
59 0