Some Notes on Debugging C Using gdb
If you want to use gdb to debug a C program, be sure to compile the program using
the -g option to the gcc compiler command. For example
gcc -g -o myprog myprog.c
The -g option tells the compiler to include information needed
by the debugger in the
compiled program (such as line numbers and names for variables).
To run the program under the control of the debugger, run gdb and give
the name of the executable program as a command-line argument:
gdb myprog
The executable should be in the current directory where you
are working. You will get the prompt "(gdb)" from the debugger.
You can enter gdb commands at this prompt. The program does not
start running automatically; you need to start it with gdb's run
command. Often, however, you will want to set some breakpoints before
you do that...
Debugging Concepts
You are probably familiar with the Java debugger in Eclipse. gdb
can do much the same thing for a C program, on the command line.
A debugger allows you to control the execution of a program by
setting breakpoints (places in the source code where the program
will pause automatically) and watchpoints (which cause the program
to paused when the value of a variable or expression changes).
A breakpoint can be conditional, meaning that the execution
will pause only if some specified condition evaluates to true.
When the program is paused, it is possible to check the values of
variables and expressions and even to set the value of a variable.
You can view information about the function call stack.
You can resume execution, or you can execute the program one step at
a time.
The rest of this document discusses gdb commands to do all these things.
Remember that these commands are given at the (gdb) prompt while
the debugger is running. The most common commands have one or two
letter equivalents (such as "c", "s", and "n" for "continue", "step", and "next").
Any command can be abbreviated to the shortest unambiguous prefix.
Program Execution
- run — Start running the program. If the program is already running,
you will be asked if you want to kill the current execution and restart from the beginning.
- quit — Quit the debugger. If the program is running, you
will be asked if you want to kill it.
- kill — Kill the current execution of the program. You
can then use run to restart.
- continue — This command and the next four are used when
the program is paused, such as by a breakpoint. The continue command will resume automatic
execution, until the end of the program or something else happens
to make it pause again, such as encountering a breakpoint.
- step — Execute the next line of the program. If the line
contains a function call, this will step into the function, stopping at the first
line of the function. ("Step into" in the Eclipse Java debugger.)
- next — Execute the next line of the program. If the line
contains a function call, the entire function call is executed (unless it contains a breakpoint
or other reason for stopping). ("Step over" in the Eclipse Java debugger.)
- finish — Resume automatic execution until the current
function returns (or something else happens to stop the execution). ("Step out" in the
Java debugger.)
- until <location> — Resume
automatic execution until the <location> is reached (or something
else happens to stop the execution).
Here and in the rest of this document, <location> can be a line number
in the current source code file or a function name, or it can be of the
form file_name:line_number to mean a line number in the specified file.
Breakpoints and Watchpoints
- break <location> — Set a
breakpoint at <location> (such as a line number or function name).
- break <location>
if <expression> — Set a conditional
breakpoint at <location>. That is, the break will only occur if the
<expression> is true. (For a numeric expression, true means
non-zero.)
- clear <location> — Remove
any breakpoint at the specified <location>.
- info break — List information about all breakpoints,
including breakpoint numbers. Breakpoint numbers can be used in the following three commands.
- disable <break-number> —
Disable breakpoint number <break-number>. Execution will not
pause at a disabled breakpoint.
- enable <break-number> —
Enable breakpoint number <break-number>.
- delete <break-number> —
Remove breakpoint number <break-number>.
- continue <number> — Can be used when
the program is paused at a breakpoint. Resumes program execution, ignoring the current
breakpoint <number> times.
- watch <expression> — Set
a watchpoint for <expression>. The program will pause execution
whenever the value of the expression changes.
A watchpoint is actually a kind of breakpoint. The info break
command will list watchpoints as well as breakpoints, including watchpoint numbers.
Watchpoint numbers can be used with the disable,
enable, and delete commands.
A watchpoint will automatically be deleted if the expression contains local variables,
and one of those variables goes out of scope.
View Information and Set Values
- where — Tells you where in the program you are.
Often, there will be several active functions that have been called, each with its
own "frame" (or activation record). The where command
prints a numbered list of active frames, with information about the current line
number in that frame. In addition to functions in your program, this
can include system calls and calls to library functions. In general, you want to look for the first frame for
a function in your own program.
- frame <number> — Select
frame number <number>, where the number is the frame
number from the where command. The print and
info locals commands are in the context
of the currently selected frame.
- print <expression> — Prints the
value of <expression>. The expression can include function calls.
- print <variable> =
<expression> — This is really just a special case of
the print command, to emphasize that it works with assignment
statements. Using an assignment statement in the print command
allows you change the value of a variable.
- print/x <expression> — Prints the
value of <expression> in hexadecimal, after type conversion to
an unsigned long int if necessary.
- info locals — Prints the name and value of all local
variables in the currently selected frame.
- backtrace full — Prints information about all frames,
including local variables. Can be abbreviated to bt f.
Without the "f" or "full", it's equivalent to where.
- list — Print ten lines from the program around the
current line.
- list <location> — Print ten lines from the program around the
specified <location>, such as a line number or function name.
- help — Print general help on using gdb.
- help <command> — Print help
about using the specified gdb <command>.
Note that it is possible to print arrays using the print
command. If the array A has been statically allocated, such as "int A[10]",
then print A will print a list containing all of the elements
of A. However, often you are working with pointers instead of arrays, and
in that case, gdb doesn't know how long the array is. If p is a pointer, and you
want to treat it as an array of 10 elements, you can say print *p@10.
This will print out the 10 items starting with *p.