Debugging with gdb

The GNU debugger (gdb) allows you to examine the internals of another program while the program executes or retrospectively to see what a program was doing at the moment that it crashed.

The gdb allows you to examine and control the execution of code and is useful for evaluating the causes of crashes or general incorrect behavior. gdb does not handle Java™ processes, so it is of limited use on a pure Java program. It is useful for debugging native libraries and the JVM itself.

Running gdb

You can run gdb in three ways:

Starting a program
Typically the command: gdb <application> is used to start a program under the control of gdb. However, because of the way that Java is launched, you must start gdb by setting an environment variable and then calling Java:
export IBM_JVM_DEBUG_PROG=gdb
java
Then you receive a gdb prompt, and you supply the run command and the Java arguments:
r <java_arguments>
Attaching to a running program
If a Java program is already running, you can control it under gdb. The process ID of the running program is required, and then gdb is started with the Java application as the first argument and the process ID as the second argument:
gdb <Java Executable> <PID>

When gdb is attached to a running program, this program is halted and its position in the code is displayed for the viewer. The program is then under the control of gdb and you can start to issue commands to set and view the variables and generally control the execution of the code.

Running on a system dump (corefile)
A system dump is typically produced when a program crashes. gdb can be run on this system dump. The system dump contains the state of the program when the crash occurred. Use gdb to examine the values of all the variables and registers leading up to a crash. This information helps you discover what caused the crash. To debug a system dump, start gdb with the Java application file as the first argument and the system dump name as the second argument:
gdb <Java Executable> <system dump>

When you run gdb against a system dump, it initially shows information such as the termination signal the program received, the function that was executing at the time, and even the line of code that generated the fault.

When a program comes under the control of gdb, a welcome message is displayed followed by a prompt (gdb). The program is now waiting for you to enter instructions. For each instruction, the program continues in whichever way you choose.

Setting breakpoints and watchpoints

Breakpoints can be set for a particular line or function using the command:

break linenumber

or

break functionName

After you have set a breakpoint, use the continue command to allow the program to execute until it reaches a breakpoint.

Set breakpoints using conditionals so that the program halts only when the specified condition is reached. For example, using breakpoint 39 if var == value causes the program to halt when it reaches line 39, but only if the variable is equal to the specified value.

If you want to know where as well as when a variable became a certain value you can use a watchpoint. Set the watchpoint when the variable in question is in scope. After doing so, you will be alerted whenever this variable attains the specified value. The syntax of the command is: watch var == value.

To see which breakpoints and watchpoints are set, use the info command:

info break
info watch
When gdb reaches a breakpoint or watchpoint, it prints out the line of code it is next set to execute. Setting a breakpoint at line 8 will cause the program to halt after completing execution of line 7 but before execution of line 8. As well as breakpoints and watchpoints, the program also halts when it receives certain system signals. By using the following commands, you can stop the debugging tool halting every time it receives these system signals:
handle sig32 pass nostop noprint 
handle sigusr2 pass nostop noprint 

Examining the code

When the correct position of the code has been reached, there are a number of ways to examine the code. The most useful is backtrace (abbreviated to bt), which shows the call stack. The call stack is the collection of function frames, where each function frame contains information such as function parameters and local variables. These function frames are placed on the call stack in the order that they are executed. This means that the most recently called function is displayed at the top of the call stack. You can follow the trail of execution of a program by examining the call stack. When the call stack is displayed, it shows a frame number at the start of the line, followed by the address of the calling function, followed by the function name and the source file for the function. For example:
#6 0x804c4d8 in myFunction () at myApplication.c

To view more detailed information about a function frame, use the frame command along with a parameter specifying the frame number. After you have selected a frame, you can display its variables using the command print var.

Use the print command to change the value of a variable; for example, print var = newValue.

The info locals command displays the values of all local variables in the selected function.

To follow the exact sequence of execution of your program, use the step and next commands. Both commands take an optional parameter specifying the number of lines to execute. However, next treats function calls as a single line of execution, while step progresses through each line of the called function, one step at a time.

Useful commands

When you have finished debugging your code, the run command causes the program to run through to its end or its crash point. The quit command is used to exit gdb.

Other useful commands are:

ptype
Prints data type of variable.
info share
Prints the names of the shared libraries that are currently loaded.
info functions
Prints all the function prototypes.
list
Shows the 10 lines of source code around the current line.
help
Displays a list of subjects, each of which can have the help command called on it, to display detailed help on that topic.