Acknowledgement


The material contained in this web page includes passages which are verbatim excerpts from two sources: the xxgdb man pages written by Po Cheung and Pierre Willard and "Debugging with GDB" written by Richard Stallman and Roland Pesch.




4.5 Debugging Tools: xxgdb and gdb


Presented below is information on how to use a source code debugging system (the Gnu DeBugger - gdb) and xxgdb, a graphical user interface to the gdb debugger under the X Window System. Together these tools provides visual feedback and mouse input for the user to control program execution through breakpoints, to examine and traverse the function call stack, to display values of variables and data structures, and to browse source files and functions.

Gdb has many commands, more than are covered here. For more information about gdb consult Debugging with GDB, a reference manual for the gdb debugger.

To use xxgdb the program must be compiled with the g++ compiler using the "-g" compiler flag set. For example, the command:

	g++ -g -o prog prog.cc
compiles the file prog.cc. The "-g" flag causes the compiler to `f insert information into the executable file (named "prog") that gdb and xxgdb require in order to work.

Starting xxgdb


To start the xxgdb simple enter its name ("xxgdb") on the command line. A graphical display will be presented that looks like this:



From top to bottom, the xxgdb display consists of the following subwindows:

File Window
Display the full pathname of the file displayed in the source window, and the line number of the caret.
Source Window
Display the contents of a source file.
Message Window
Display the execution status and error messages of xxgdb.
Command Window
Provide a list of the common gdb commands which are invoked by simply clicking the LEFT mouse button.
Dialogue/Display Window
Provides a window for displaying output from the program or from gdb. Alternatively, any gdb command can be entered in this window.
In the initial xxgdb window above, the File Window current has "No Source File". During a debugging session the actual name of the source file being viewed will be shown here. The Source Window in the above picture is empty. During a debugging session the relevant source code will appear in this subwindow. The Message Window above has "Ready for execution." which is the current status of gdb. Other status information will appear in this place throughout a session. The Command Window in the middle of the screen has 20 buttons each of whose function is explained below. The Dialogue/Display window initially contains the disclaimer message regarding gdb. This disclaimer begins with the words "GDB comes with...". The relative sizes of the source window, command window, and the dialogue/display window can be adjusted by dragging the grip (a small square near the right edge of a horizontal border) with the LEFT mouse button down.


Selecting, Searching and Quitting


The command window, in the middle of the xxgdb display, contains three buttons that are used to begin debugging a file, quitting xxgdb, and searching through the source code of the program being debugged. These buttons are:
file
Pop up a directory browser that allows the user to move up and down in the directory tree, to select a text file to be displayed, to select an executable file to debug, or to select a core file to debug.Directory entries are marked with a trailing slash (`/') and executables with a trailing asterisk (`*'). Filenames beginning with a dot (`.') or ending with a tilde (`~') are not listed in the menu.
quit
Exit xxgdb.
search
Pop up a search panel which allows both forward (>>) and reverse (<<) search of text strings in the source file. Hitting carriage return after entering the search string will begin a forward search and pop down the search panel.

It is important to remember that the file you select for debugging must be an executable file that has been compiled with by g++ with the "-g" compiler option.

When xxgdb loads the executable file it will display in the upper subwindow (the Source subwindow) the source text of the program being debugged. This subwindow will be scrolled/refreshed during the execution of the program so that the current line being executed is always visible. The contents of this window can be searched using the search button as described above.


Setting Breakpoints


The principal purposes of using a debugger are so that you can stop your program before it terminates; or so that, if your program runs into trouble, you can investigate and find out why.

A breakpoint makes your program stop whenever a certain point in the program is reached. When the program is stopped at a breakpoing, you may then examine and change variables, set new breakpoints or remove old ones, and then continue execution. It is often necessary to eliminate a breakpoint or watchpoint once it has done its job and you no longer want your program to stop there. This is called deleting the breakpoint. A breakpoint that has been deleted no longer exists; it is forgotten.

Breakpoints can be set and deleted using the following buttons in the Command Window:

break
Stop program execution at the line or in the function selected. To set a breakpoint in the program, place the caret at the start of the source line or on the function name and click the break button. A stop sign will appear next to the source line.
tbreak
Set a breakpoint enabled only for one stop. This is the same as the break button except the breakpoint is automatically disabled the first time it is hit.
delete
Remove the breakpoint on the source line selected or the breakpoint number selected.

It is not necessary to delete a breakpoint to proceed past it. GDB automatically ignores breakpoints on the first instruction to be executed when you continue execution without changing the execution address.


Controlling the Program's Execution


The program being debugged can be run and, when breakpoints are encountered, its future execution can be controlled via a set of buttons in the Command Window. The relevant buttons are:
run
Begin program execution.
cont
Continue execution from where it stopped.
next
Execute one source line, without stepping into any function call.
step
Execute one source line, stepping into a function if the source line contains a function call.
finish
Continue execution until the selected procedure returns; the current procedure is used if none is selected.

Continuing means resuming program execution until your program completes normally, experiences an error or reaches a breakpoing. In contrast, stepping means executing just one more "step" of your program.

The step button continues running your program until control reaches a different source line either in the same or a different function. In contrast the next button Continues to the next source line in the current function. Similar to step, but any function calls appearing within the line of code are executed without stopping.Execution stops when control reaches a different line of code at the stack level which was executing when the next command was given.

A typical technique for using stepping is to set a breakpoint at the beginning of the function or the section of your program where a problem is believed to lie, run your program until it stops at that breakpoint, and then step through the suspect area, examining the variables (see below)that are interesting, until you see the problem happen.


Examining the Execution History


When your program has stopped, at a breakpoint or because it experienced a fatal error, it is often useful to examine the sequence of method invocations that have led to the current point of execution and to examine the arguments and local variables of the current method. Information such as this is obtained by examining the "call stack".

Each time your program invokes a method, the information about where in your program the invocation was made from is saved in a block of data called a stack frame. The frame also contains the arguments of the call and the local variables of the function that was called. All the stack frames are allocated in a region of memory called the call stack. When your program stops, the GDB commands for examining the stack allow you to see all of this information. When your program stops, GDB automatically selects the currently executing frame and describes it briefly as the frame command does.

GDB assigns numbers to all existing stack frames, starting with zero for the current frame, one for the frame that called it, and so on upward. These numbers do not really exist in your program; they are assigned by GDB to give you a way of designating stack frames in GDB commands.

Most commands for examining the stack and other data in your program work on whichever stack frame is selected at the moment. In particular, whenever you ask GDB for the value of a variable in your program, the value is found in the selected frame. There are special GDB commands to select whichever frame you are interested in.

The Command Window contains several buttons for examining the call stack and its frames. These commands are:

stack
Show a stack trace of the functions called.
up
Move up one level on the call stack.
down
Move down one level on the call stack.
args
Print the arguments of the selected frame.
locals
Print the local variables of the selected frame.

For the up and down commands it is important to remember that "up" in the call stack advances away from the method currently being executed, backward in time, toward the outermost frame, to higher frame numbers, to frames that have existed longer. Conversely, "down" advances toward the method currently being executed, forward in time, toward the innermost frame, to lower frame numbers, to frames that were created more recently.


Examining Variables


Debugging often entails looking at the values of variables and objects to determine when an error has occurred and what may have contributed to the error. With xxgdb both the value of built-in types (int, float, char, char*,...) and the values of complicated objects can be viewed.

The value of a variable or object can be viewed by identifying the variable or object (see below) and using one of the following command buttons:

print
Print the value of a selected variable or object
print*
Print the value of the object the selected variable is pointing to.
display
Display the value of a selected variable in the display window, updating its value every time execution stops.
undisplay
Stop displaying the value of the selected variable in the display window. If the selected variable is a constant, it refers to the display number associated with an expression in the display window.
The value of a variable can be examined in one of several ways. In the simplest case, the variable is not a pointer and its name is visible in the Source Window. In this case, simply highlight the name of the variable in the Source Window and press the "print" button. The value will appear in the Dialogue/Display window. If the variable is a pointer to an object, highlight the name of the pointer variable and use the "print*" command button. The value will, as before, appear in the Dialogue/Display window. If the name of the variable is not currently visible in the Source Window you can type its name in the Dialogue/Display area, highlight the name in the Dialogue/Display area, and use the "print" or "print*" command buttons as before.


Next Stop


Last Update: September 4, 1995 / kafura@cs.vt.edu