Debugging - Using the Java Debugger (jdb)

24 Nov 2008

 

Goals
  1. Getting started with Java Debugger using command line tool JDB
  2. Doing simple debug operations using JDB
Let us get started
  • Write a simple java program and save it as Sample.java.
import java.lang.*;

public class
Sample
{
public static void main(String[] args)
{
System.out.println("Brought to you by "+getName(10));

}

public static String getName(int i)
{
int j = 20;
while(i>0)
i--;
System.out.println("Value of J is : "+j);
return http://krishnabhargav.blogspot.com;
}
}




  • Compile the java program such that the symbols are also generated, which is useful for debugging purposes. This is done as shown



javac -g Sample.java



  • Load the debugger with the Sample class. You do that with the command shown below



jdb Sample



  • Before we start any further, let us look at the list of commands that are useful for us. To get a help, type "help" in the jdb console menu.

    • list - display ten lines of source code, around the line at which the execution stopped


    • stop in <class>.<methodName> - breakpoint at the specified methodName in the Class <class>


    • stop at <class>:<lineNumber> - breakpoint at the specified line number in the class


    • locals - list the local variables in the current scope


    • dump <obj reference> - dumps the object whose reference is specified


    • print <obj reference> - prints the object whose reference is specified


    • set x = 10 - set's the value of the variable x to 10


    • eval 100+500 - evaluates the expression passed and displays the result.






  • Now let us start, first we need to set a breakpoint at main() method. We do that using "stop at" command.



stop at Sample.main



  • Now start running the program, use the "run" command.



run



  • You would notice the program to stop when it hits the breakpoint



Breakpoint hit: "thread=main", Sample.main(), line=7 bci=0
7 System.out.println("Brought to you by "+getName(10));



  • Now type the list command, and you get to see the code listing as shown



3    public class Sample
4 {
5 public static void main(String[] args)
6 {
7 => System.out.println("Brought to you by "+getName(10));
8
9 }
10
11 public static String getName(int i)
12 {



  • The => shows where the break point has been hit. Now we have option to step into the getName() method. For that type



step



  • Now type "list" again. The code listing would be shown



9            }
10
11 public static String getName(int i)
12 {
13 => int j = 20;
14 while(i>0)
15 i--;
16 System.out.println("Value of J is : "+j);
17 return http://krishnabhargav.blogspot.com;
18 }



  • Now let us skip the loop execution. For that let us first put a breakpoint at line number 16



stop at Sample:16



  • Now to resume execution, type "cont" command. It would execute till it hits the next breakpoint



cont



  • Now let us look at the local variables in the current context. For that type "locals" in the console as shown



main[1] locals
Method arguments:
i = 0
Local variables:
j = 20



  • Now let us try to modify the value of j on the fly, instead of 20, let us put the value as 100. For that



set j = 100



  • Now let us go back to the calling method. For that, type "step up"



step up


main[1] step up
> Value of J is : 100

Step completed: "thread=main", Sample.main(), line=7 bci=20
7 System.out.println("Brought to you by "+getName(10));



  • Now let us finish the execution till the end. For that just type "cont" again. You see the listing as shown.



main[1] cont
> Brought to you by http://krishnabhargav.blogspot.com


What next?


We have seen how to look at the local variables. We also have seen how to change the value of a variable in scope. But we have not seen how to work with dump <ref>, print <ref> and the other useful "eval" command. You could figure out doing this. But for now, try to repeat the debugging process again. Then set up a breakpoint at main() method and when it breaks, just type in "dump this". See what you get? You get an exception saying that you are currently either in a static method or native method, so to test the dump functionality, you would have to have a object in your scope. And then you can dump that. Suppose you have an instance of Point in your context. Then you can set pt.x using "set pt.x = 100", by this I mean to show that you can use set to manipulate all variables, even those that belong to an object.



Remote Debugging with JDB


Other important thing that we are missing in this tutorial is remote debugging using JDB. I would not present a step by step way to do that but for remote debugging a program, you need to

1. Start the program using Java command, as shown



java -Djava.compiler=NONE -Xnoagent -Xdebug
-Xrunjdwp:transport=dt_socket,address=2502,server=y,suspend=y
Sample


2. Attach jdb from the command line to the server. assuming it is running on localhost, it is done as shown.



jdb -attach localhost:2502


References


JDB Documentation