This tutorial provides an introduction to debugging Java programs on Linux machines using jdb, the standard Java debugger. More detailed information can be found in the following documents:
The programs and data file discussed in this tutorial is in the Linux directory /home/allen/cs250/java/jdb.The jdb man page The javac man page The java man page
To illustrate debugging, we use a simple Java program called removeDuplicates, which reads integers from a file called 'numbers' and displays one instance of every different integer in the file. For instance, if the file contains the integers
2 3 4 5 6 3 4 5 6 7then the program displays the following output:
The unique integers in this series are: 2 3 4 5 6 7Here is a listing of the program, with line numbers added on the left:
1 public class removeDuplicates {
2 // problem 1.1 on page 21
3 static int[] N = new int[1000];
4 static int x, m;
5
6 public static boolean xinN() {
7 boolean result = false;
8 for (int i=0; i<m; i++)
9 if (N[i]==x)
10 result = true;
11 return result;
12 }
13
14 public static void main (String[] args) {
15 pseudoKeyboard k = new pseudoKeyboard("numbers");
16 m = 0;
17 x = k.readInt();
18 while (!k.eof()) {
19 if (!xinN()) {
20 N[m] = x;
21 m++;
22 }
23 x = k.readInt();
24 }
25 System.out.println("The unique integers in
this series are:");
26 for (int i=0; i<m; i++)
27 System.out.println(N[i]);
28 }
29 }
This program uses an auxiliary class pseudoKeyboard for reading integers, but the details of that class are not necessary to this jdb illustration.
[allen@lynx20 bozo]$ javac -g removeDuplicates.java [allen@lynx20 bozo]$ jdb removeDuplicates Initializing jdb... 0xb0:class(removeDuplicates) >Here, the second line starts the Java debugger with this program. The last line gives the jdb prompt >, which will appear until you exit the debugger by typing exit.
> help
** command list **
threads [threadgroup] -- list threads
thread <thread id>
-- set default thread
suspend [thread id(s)] -- suspend threads (default:
all)
resume [thread id(s)] -- resume threads
(default: all)
where [thread id] | all -- dump a thread's stack
wherei [thread id] | all -- dump a thread's stack, with pc
info
threadgroups
-- list threadgroups
threadgroup <name>
-- set current threadgroup
print <id> [id(s)]
-- print object or field
dump <id> [id(s)]
-- print all object information
locals -- print all local variables in current stack frame
classes
-- list currently known classes
methods <class id>
-- list a class's methods
stop in <class id>.<method>[(argument_type,...)] -- set a
breakpoint in a methodstop at <class id>:<line> -- set a breakpoint
at a line
up [n frames]
-- move up a thread's stack
down [n frames]
-- move down a thread's stack
clear <class id>.<method>[(argument_type,...)]
-- clear a breakpoint in a method
clear <class id>:<line> -- clear a breakpoint
at a line
step
-- execute current line
step up
-- execute until the current method returns to its caller
stepi
-- execute current instruction
next
-- step one line (step OVER calls)
cont
-- continue execution from breakpoint
catch <class id>
-- break for the specified exception
ignore <class id>
-- ignore when the specified exception
list [line number|method] -- print source code
use [source file path] -- display or change the
source path
memory
-- report memory usage
gc
-- free unused objects
load classname
-- load Java class to be debugged
run <class> [args]
-- start execution of a loaded Java class
!!
-- repeat last command
help (or ?)
-- list commands
exit (or quit)
-- exit debugger
>
> stop at removeDuplicates:23
Breakpoint set at removeDuplicates:23
> run
The last line begins execution of the program, which will go until the breakpoint is reached. The following message will appear:
> run
run removeDuplicates ls
running ...
main[1]
Breakpoint hit: removeDuplicates.main (removeDuplicates:23)
main[1]
main[1] dump removeDuplicates
removeDuplicates = 0xb0:class(removeDuplicates) {
superclass = 0x2:class(java.lang.Object)
loader = (sun.misc.Launcher$AppClassLoader)0xb1
static int m = 1
static int x = 2
static int N[] = { 2, 0, 0, ... }
main[1]
gives the values of the variables m, x, and N just before the second number is read from the file "numbers". To continue execution, type "cont" which will lead to another break at the next execution of line 23:
main[1] cont
main[1]
Breakpoint hit: removeDuplicates.main (removeDuplicates:23)
main[1] dump removeDuplicates
removeDuplicates = 0xb0:class(removeDuplicates) {
superclass = 0x2:class(java.lang.Object)
loader = (sun.misc.Launcher$AppClassLoader)0xb1
static int m = 2
static int x = 3
static int N[] = { 2, 3, 0, ... }
main[1]
This process can be repeated as long as desired, and for as many breakpoints as desired. When execution is to be resumed without any breakpoints, they must be cleared before the "cont" instruction is issued.
main[1] clear
Current breakpoints set:
removeDuplicates:23
main[1] clear removeDuplicates:23
Breakpoint cleared at removeDuplicates: 23
main[1] cont
The unique integers in this series are:main[1]
2
3
4
5
6
7
Current thread "main" died. Execution continuing...
>
removeDuplicates exited
[allen@lynx20 bozo]$
Note here that the command "clear" without any arguments simply lists all the breakpoints that are currently set. When program execution terminates, the output is displayed and the debugger exited, just as if a normal run of the program had taken place.
Other jdb functions can be learned by experimentation, using the help command as a starting point.