Debugging with gdb
Part 3 of A GNU/Unix development environment primer
So now you have your program compiled. How do you debug it? The
simplest way is to edit the code frequently, telling it to print its
status here, to print something when it reaches that point, etc. Doing
this involves lots of trial and error, though, and a painful process of
editing and recompiling. Much of this can be avoided by using
gdb - the GNU debugger. The GNU debugger is a powerful
successor to the Unix debugger dbx. It has an excellent
command-line interface - which is what this primer will discuss - but
it becomes particularly powerful within GNU's emacs. (Thanks
to Doug Rohde, whose Web document ``An introduction to using
gdb under Emacs'' we used and even often pirated (with his
permission) in preparing this section.)
A graphical X-based version of gdb, named xgdb, exists,
but only sporadically. Checking to see if it is on your particular
machine is worthwhile.
Basics
Say you are debugging ``prog''. Compile ``prog'' with the `g' flag (see
the section on g++ for more information about this flag), and
fire up gdb by typing ``gdb prog'' at the shell prompt.
This will load in the program, and from there you will get a
command-line prompt, from then you can issue any of a number of
commands.
- help
- is the command to access gdb's extensive online help
system. With no arguments, this will describe the help system.
- file
- changes the executable file being examined. If you type
``file foo'', then the executable under examination will become
``foo''.
- quit
- exits you from gdb.
- run
- begins your program at the beginning. Type what you would type at
the shell prompt, but replace the executable's name with
``run''. For example, if you normally run your program by
typing ``a.out 6 < inputfile > outputfile'', you should start
it in gdb with the command ``run 6 < inputfile >
outputfile''.
- kill
- terminates the program. This is useful since the executable
cannot be modified until gdb is done with it, so you cannot
make your program until the program is terminated.
- make
- works just like a call to make from the shell
prompt. It saves you from going between the shell prompt and the
gdb prompt all the time just to recompile your program.
- list
- lists the ten lines surrounding the current line of the
program. If you type ``list 100'', it lists the ten lines
surrounding line 100.
Examining your program's state
When your program terminates abnormally, either due to an internal
error or due to a user break from a control-C, or when your program is
stopped due to reaching a breakpoint (described below) the program's
state is maintained for examination within gdb. At this point
you can examine it to help you determine where the termination occurred
and what the variables' values were to make it stop there.
- where
- displays the call stack.
- up
- changes the function call under consideration to be the one
above the current function call in the call stack. This allows you to
investigate variable values in this newly current function call.
- down
- moves the function call under consideration to be the one
just below the current function in the call stack.
- print
- displays the value of an expression in a readable format.
The expression can be a single variable, such as i, or a more
complicated expression, such as *(A[i]->next). The expression
could even tweak values: ``print i = 6'' will change the value
of i to six. Or the expression can include a function call:
``print Fib(2)''. Be careful with assigning or calling a
function call using print! The potential for messing something
up is high.
Setting breakpoints
Normally gdb will run your program until abnormal or normal
termination. You can investigate your program's behavior as it runs
using breakpoints. The interface is not convenient, but it can work well
if you have the patience.
- break
- sets a breakpoint. Given a function name, break
will set the breakpoint at calls to the function. If given a line
number, it sets a breakpoint to the point when that line of source code
is reached.
- delete
- deletes the breakpoint whose number is specified by the
argument. (A number is assigned to each breakpoint when it is
created.)
- step
- executes the current line of code. If the line contains a
function call, step enters that function.
- next
- executes the current line of code, skipping over code
within function calls.
- finish
- continues execution until the current function call is
complete.
- continue
- resumes execution of the program.
Last updated 16 Feb 1996.