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.