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.
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
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:
- 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
- Exit xxgdb.
- Pop up a search panel which allows both forward (>>) and reverse
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.
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:
- 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.
- 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.
- Remove the breakpoint on the source line selected or the breakpoint
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
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:
- Begin program execution.
- Continue execution from where it stopped.
- Execute one source line, without stepping into any function call.
- Execute one source line, stepping into a function if the source
line contains a function call.
- 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
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:
- Show a stack trace of the functions called.
- Move up one level on the call stack.
- Move down one level on the call stack.
- Print the arguments of the selected frame.
- 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.
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
- Print the value of a selected variable or object
- Print the value of the object the selected variable is pointing
- Display the value of a selected variable in the display window,
updating its value every time execution stops.
- 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.
Last Update: September 4, 1995 / email@example.com