GDB - The GNU Debugger
The GNU debugger (GDB) allows a programmer to examine the internal
operation of a running program. Variables and expressions can be
printed and values changed. The program can be executed a line at
a time or be forced to pause at specific locations. For programs
that step outside the bounds of properly allocated memory, GDB can
run a program while constantly watching specified memory location
to see when they change. GDB is also useful to perform a
post-mortem analysis of a program that has crashed and left behind
a core file (more below).
GDB is best used with programs that have been compiled using
the -g option. This places information in
the executable code that lets the debugger know which parts of
the executable correspond to which lines in source code files,
which memory locations correspond to which variable names, and
so forth. Programs compiled with the -g option are
usually larger and slower than they would be otherwise.
GDB is used by typing in commands at a prompt. To reduce the
amount of typing, most commands have abbreviations, many as small
a single letter. Because some commands are used successively,
GDB has the feature that when an empty command line is entered
(no characters, just the return key) it will repeat the previous
command. This point is important to understand in the efficient
use of GDB.
The GDB commands fall naturally into several categories. An
explanation of how to start gdb and a description of some of the
most common commands is given below. Where they exist, the
command abbreviations are given as well.
GDB is started by typing gdb on the command line along
with the name of the executable file to be debugged. If the
program takes command line arguments, they are not given here. A
splash message is displayed and then the GDB prompt is given,
(gdb). This does not actually run the executable, but
loads it in preparation for execution.
Running a Program
The commands for starting and stopping a program are given below.
- r or run
- This command (re)starts running the program from the
beginning. If the program takes command line arguments, these
are placed after the run (or r) command.
GDB is smart enough to remember the command line arguments, so
subsequent restarts of the program do not need to explicitly
list them. For example, in the following session
(gdb) r arg1 arg2 arg3
... More debugging session here
these two program restarts provide the exact same set
of arguments to the program.
- q or quit
- This command exits the debugger.
- n or next
- Execute the next source code line of the program. If the
next line to be executed involves a function call, then the
entire function call is executed. This is similar to the
"step over" feature found in other debuggers.
Every time the execution stops, the source code line of the
line about to be executed is printed. Not the line
that was just executed. This is one of the most common
misunderstandings about any debugger.
This command takes an optional integer argument which
specifies the number of steps to take.
- s or step
- Execute the next source code line of the program. If the
next line to be executed involves a function call, then step
into that function. This is similar to the "step
into" feature found in other debuggers.
Using a combination of next and step
commands it is possible to begin executing in the
main() function of a program and then step into
functions of interest, quickly arriving at a function that may
be buried deep within the executing program.
It must be noted that a program can not be started using
the next and step commands. If single
stepping through a program from the beginning is desired, a
breakpoint must be set on the
This command also takes an optional integer argument
specifying the number of steps to take.
- c or continue
- Continue the execution of the program until the next
breakpoint or the program ends.
- Complete execution of the current function and stop after
returning. This is very useful after stepping into a function
by mistake, or after having verified that the function is
- Return immediately from the current function without
executing the rest of the code for the function. This command
takes an optional argument, which is the value to be returned.
This command is useful for working around functions that are
known to be defective, but must be used with caution.
- bt or backtrace
- Print the execution stack.
When a program stops because of a breakpoint or an error,
chances are good that it is "executing" in multiple
functions. Function A has called function B which in turn is
calling function C which called function D when the program
stopped. Did the program stop in function A, B, C or D? The
answer is yes, it stopped in all of them.
When a function calls another, it is placed on a stack of
executing functions. The information associated with any one
function that is in the process of being executed is called a
frame. The backtrace command prints out
the stack frame of executing functions. This is useful in
knowing exactly how the function of interest (the last one
called) was called.
The execution stack has a direction. The
main() function is considered to be at the top of
the stack. The innermost function being executed is
considered to be at the bottom.
- Move up the execution stack.
- Move down the execution stack. The up and
down commands change the focus of the GDB
commands. If a program has a serious error such as a
segmentation fault, it will invariably break inside a library
function, during input or output. The code at these levels
can not be listed, and in any event, the problem is not likely
the fault of the libraries. In order to examine the values of
variables in the functions that called the library functions,
it is necessary to move up the stack until the desired level
has been found.
Moving up or down the stack does not execute any code in
the innermost functions. In order to finish the execution of
code in any given function, the finish command must
- l or list
- List part of the program source code. Only 10 lines are
listed. If no arguments are given to this command the current
line to be executed is shown in the middle of the 10 line
listing. If no arguments are given and the last command was
also a list command, then the 10 lines following the
lines already shown are displayed. This makes it possible to
list large sections of code by using the list command
multiple times. (Or by using the list command once
and hitting the enter key multiple times to perform last command
The list command takes optional arguments.
Some of these (shown as examples) are
- list 20
- List starting at line 20.
- list my_function1
- List starting at the function
- list +30
- List the next 30 lines. This gets around the 10 line
limitation mentioned above. This default number of lines to
be listed can be changed using the command set listsize
30. The current setting of the number of lines to be
listed by default can be examined using the command
- list 10,75
- List lines 10 through 75.
- p or print expression
- Print the given expression. It must be emphasized that
this command is capable of printing expressions,
which can be very complex. The expressions can contain
multiple variables. Nearly anything that can be evaluated as
a valid C or C++ expression is legal.
Only the variables that are availiable in the current
function being executed can be used in expressions. This
includes any global variables that are available. Variables
in other functions are not available.
This command will print out as much as it intelligently
can, given the type of the expression. If printing out the
value of a
char * it will print the value of the
C style string pointed at. Arrays can be printed out as well,
simply by giving the name of the array as the expression.
However, this assumes that the size of the array is known, so
only explicitly sized arrays can be printed out this way.
Printing out a class instance will show all of the data
members for that instance.
Because the print command can evaluate any C/C++
expression, it can also evaluate assignment expressions. This
is how values are changed using the debugger. For example if
the current function contained an integer variable
a that had been assigned the value of 7, the
following session fragment shows how the value of a is
examined, set to have the value of 4 and re-examined:
(gdb) p a
$1 = 7
(gdb) p a = 4
$2 = 4
(gdb) p a
$3 = 4
Breakpoints are places in the program being
examined where the execution is forced to stop. Breakpoints can
be inserted and deleted during a debugging session. No changes
are made to the source code. Temporary breakpoints can also be
created, which exist only until they are encountered the first
- b or break
- This command sets a breakpoint. If it is not given an
argument it places the breakpoint at the current location in the
code. This command can take different kinds of options, some of
which are shown below as examples.
- break 30
- Set a breakpoint at line 30
- break my_function2
- Set a breakpoint at the first executable statement in
- break +10
- Set a breakpoint 10 lines after the current position.
- break 40 if *p == 'c'
- Set a breakpoint at line 40 that will break only if the
*p == 'c' evaluates to true at that
point in the program. This is a very powerful form of
setting breakpoints. The breakpoint position can be set
using any of the forms given previously: by line number, by
function name, or by relative position. The condition can
be any valid C/C++ expression that evaluates to a
non-zero/zero value, which is treated as true or false.
Each breakpoint is given an integer number when it is
assigned. All references to a particular breakpoint are given
with that number. The number is printed out when the
breakpoint is assigned, but can be printed out as explained below.
- Set a temporary breakpoint. A temporary breakpoint is one
that is automatically deleted when it is encoutered. This is
useful for one-time situations, getting out of long loops, and
Temporary breakpoints take all of the arguments for setting
them that regular breakpoints take.
- info break
- Display all of the breakpoints set in the program. The
information printed includes the breakpoint number, the location
of the breakpoint, and the number of times that the breakpoint
has been examined.
- d or delete
- If this command is given no arguments, then all breakpoints
are deleted. Otherwise, this command takes a list of integer
arguments, the breakpoints to be deleted.
- Delete any breakpoints on the next line to be executed.
This command can also take arguments, which are illustrated
- clear my_function3
- Clear any breakpoints at the beginning of
- clear 25
- Clear any breakpoints found on line 25.
Watchpoints are used to examine the value of an expression at
every step of the program, stopping whenever the value of the
expression changes. Watchpoints are invaluable in finding out
what function is trashing a particular section of memory that
should not be changing. Because the watchpoint is examined with
every step of the program, watchpoints make a program hundreds or
thousands of times slower. But sometimes they are the best tool
for the job.
- watch expression
- Set a watchpoint for the expression. The program will break
whenever the value of the expression changes from its current value.
Watchpoints are listed using the info break command