Here are some of the usful actions that gdb can perform:
For C and C++ programs, gdb and ddd are debuggers that you can use.
ddd
is a easy-to-use GUI wrapper around an inferior debugger (gdb
for GNU compiled C or C++ code). ddd allows you to interact
with the debugger by using either GUI menu options or the under-lying debugger's
command line interface. In addition, ddd
automatically displays source code when breakpoints are reached.
There are some example programs and some documentation on using gdb
to debug them that you can copy from here:
/home/newhall/public/gdb_examples/
-g
option can be debugged using GNU's debugger gdb (actually, you
can use gdb on code that is not compiled with -g, but unless you like trying to
figure out how assembly code sequences map to your source code I wouldn't
recommend doing so). Also, do not compile with an optimization flag (i.e.
don't use -O2), or gdb will have a hard time mapping optimized machine code
to your source code. For example:
% gcc -g myprog.c
To start gdb, invoke gdb on the executable file. For example:
% gdb a.outIf your program terminates with an error, then the operating system will often dump a core file that contains information about the state of the program when it crashed. gdb can be used to examine the contents of a core file:
% gdb core a.outOne good way to get started when you are trying to track down a bug, is to set breakpoints at the start of every function. In this way, you will quickly be able to determine which function has the problem. Then you can restart the program and step through the offending function line-by-line until you locate the problem exactly.
ddd is invoked in a similar way:
% ddd a.out
Commonly used gdb commands
--------------------------
gdb also understands abreviations of commands, so you can just type up to
the unique part of a command name ("cont" for "continue", or "p" for "print")
help List classes of all gdb commands
help <topic> Shows help available for topic or command
where Shows stack: sequence of function calls executed so far
(or backtrace) (good for pinpointing location of a program crash)
(or bt)
frame Shows all stack frames
frame <frame-num> Sets current stack frame to <frame-num>
run Starts program at the beginning
break <line> Sets breakpoint at line number <line>
break <func-name> Sets breakpoint at beginning of function <func-name>
break main Sets breakpoint at beginning of program
continue Continues execution from breakpoint
condition <bp-num> <exp> Sets breakpoint number <bp-num> to break only if
conditional expression <exp> is true
info break Shows current breakpoints
disable [breakpoints] [bnums ...] Disable one or more breakpoints
enable [breakpoints] [bnums ...] Enable one or more breakpoints
clear <line> Clears breakpoint at line number <line>
clear <func-name> Clears breakpoint at beginning of function <func-name>
delete <bp-num> Deletes breakpoint number <bp-num>
delete Deletes all breakpoints
step (or s) Executes next line of program (steping into functions)
step <count> Executes next <count> lines of program
next (or n) Like step, but treats a function call as a single
next <count> instruction
until <line> Executes program until line number <line>
print <exp> (or inspect <exp> Displays the value of expression <exp>
display <exp> Automatic display of <exp> each time a breakpoint reached
whatis <exp> Shows data type of expression <exp>
info locals Shows local variables in current stack frame
set variable <variable> = <exp> Sets variable <variable> to expression <exp>
list Lists next few lines of program
list <line> Lists lines around line number <line> of program
list <start> <end> Lists line numbers <start> through <end>
list <func-name> Lists lines at beginning of function <func-name>
quit Quits gdb
Also, you can give just the unique prefix of a command as the command and
gdb will execute it. For example, rather than entering the command
print x, you can just enter p x to print out the value
of x.
The up and down arrow keys can be used to scroll
through previous command lines, so you do not need to re-type them each time.
If you just hit RETURN at the gdb prompt, gdb will execute the
most recent previous command again. This is particularly useful if you are
steping through the execution, then you don't have to type next
each time you want to execute the next instruction, you can just type
it one time and then hit RETURN.
For example, to set a break point in funciton pinPage of the BufMgr class,
I'd do the following:
Run 1: badprog.c
% gcc -g badprog.c #-- compile program with -g flag
% gdb a.out #-- invoke gdb with the executable
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) break main #-- set a breakpoint at the begining of the program's execution
Breakpoint 1 at 0x8048436: file badprog.c, line 36.
(gdb) run #-- run the program
Starting program: /home/newhall/public/gdb_examples/a.out
Breakpoint 1, main () at badprog.c:36 #-- gdb stops at breakpoint
36 int arr[5] = { 17, 21, 44, 2, 60 };
(gdb) list #-- list the source code near the break point
31 return 0;
32 }
33
34 int main(int argc, char *argv[]) {
35
36 int arr[5] = { 17, 21, 44, 2, 60 };
37
38 int max = arr[0];
39
40 if ( findAndReturnMax(arr, 5, max) != 0 ) {
(gdb) list 11 #-- list source code around line 11
11 // this function should find the largest element in the array and
12 // "return" it through max
13 // array: array of integer values
14 // len: size of the array
15 // max: set to the largest value in the array
16 // reuturns: 0 on success and non-zero on an error
17 //
18 int findAndReturnMax(int *array1, int len, int max) {
19
20 int i;
(gdb) list #-- list the next few lines of code
21
22 if(!array1 || (len <=0) ) {
23 return -1;
24 }
25 max = array1[0];
26 for(i=1; i <= len; i++) {
27 if(max < array1[i]) {
28 max = array1[i];
29 }
30 }
(gdb) next #-- execute the next instruction
38 int max = arr[0];
(gdb) #-- hitting Enter executes the previous command (next in this case)
40 if ( findAndReturnMax(arr, 5, max) != 0 ) {
#-- also you can use the up and down arrows to scroll through previous commands
(gdb) print max #-- print out the value of max
$1 = 17
(gdb) p arr #-- p is short for the print command
$2 = {17, 21, 44, 2, 60}
(gdb) step #-- step into the function call
#-- if we had entered 'next' the entire function call would have been executed
findAndReturnMax (array1=0xbfc5cb3c, len=5, max=17) at badprog.c:22
22 if(!array1 || (len <=0) ) { #-- 'step' takes us to the entry point of findAndReturnMax
(gdb) print array1[0] #-- lets see what the param values are
$3 = 17
(gdb) p max
$4 = 17
(gdb) list
17 //
18 int findAndReturnMax(int *array1, int len, int max) {
19
20 int i;
21
22 if(!array1 || (len <=0) ) {
23 return -1;
24 }
25 max = array1[0];
26 for(i=1; i <= len; i++) {
(gdb) break 26 #-- set a breakpoint at line 26 (inside findAndReturnMax)
Breakpoint 2 at 0x80483e7: file badprog.c, line 26.
(gdb) cont #-- continue the execution
Continuing.
Breakpoint 2, findAndReturnMax (array1=0xbfc5cb3c, len=5, max=17) #-- gdb hits the next breakpoint
at badprog.c:26
26 for(i=1; i <= len; i++) {
(gdb) p i
$5 = 0
(gdb) n #-- n is short for next
27 if(max < array1[i]) {
(gdb) display max #-- display will print out the value everytime we hit a breakpoint
1: max = 17
(gdb) display array1[i]
2: array1[i] = 21
(gdb) break 27 #-- set a breakpoint inside the loop
Breakpoint 3 at 0x80483f0: file badprog.c, line 27.
(gdb) cont #-- continue execution
Continuing.
Breakpoint 3, findAndReturnMax (array1=0xbfc5cb3c, len=5, max=21)
at badprog.c:27
27 if(max < array1[i]) {
#-- display prints these out:
2: array1[i] = 44
1: max = 21
(gdb) cont
Continuing.
Breakpoint 3, findAndReturnMax (array1=0xbfc5cb3c, len=5, max=44)
at badprog.c:27
27 if(max < array1[i]) {
2: array1[i] = 2
1: max = 44
(gdb) cont
Continuing.
Breakpoint 3, findAndReturnMax (array1=0xbfc5cb3c, len=5, max=44)
at badprog.c:27
27 if(max < array1[i]) {
2: array1[i] = 60
1: max = 44
(gdb) cont
Continuing.
Breakpoint 3, findAndReturnMax (array1=0xbfc5cb3c, len=5, max=60)
at badprog.c:27
27 if(max < array1[i]) {
2: array1[i] = 17
1: max = 60 #-- so max is 60 here
(gdb) where #-- show the stack frames
#-- findAndReturnMax is the active function at line 27, it was called by main at line 40:
#0 findAndReturnMax (array1=0xbfd043ec, len=5, max=60) at badprog.c:27
#1 0x08048479 in main () at badprog.c:40
frame 1 #-- move into main's calling context (stack frame 1) to examine main's state
#1 0x08048479 in main () at badprog.c:40
40 if ( findAndReturnMax(arr, 5, max) != 0 ) {
(gdb) print max #-- in main's stack frame max is 17
$1 = 17
(gdb) cont #-- continue execution
Continuing.
max value in the array is 17 #-- main prints out value of max after function call
#-- This looks like a bug:"
#-- findAndReturnMax set max to 60, but 60 isn't getting "passed back" to main after the call
#-- to fix this we need either have findAndReturnMax return the value of max or pass max by reference
(gdb) quit #-- quit gdb
The program is running. Exit anyway? (y or n) y
Run 2: segfaulter.c
% gdb segfaulter
GNU gdb 6.4.90-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) run #-- just run segfaulter and let it seg fault
Starting program: /home/newhall/public/gdb_examples/segfaulter
Failed to read a valid object file image from memory.
Program received signal SIGSEGV, Segmentation fault.
0x080483e1 in initfunc (array=0x0, len=100) at segfaulter.c:15
15 array[i] = i;
(gdb) where #--- let's see where it segfaulted
#0 0x080483e1 in initfunc (array=0x0, len=100) at segfaulter.c:15
#1 0x0804846e in main () at segfaulter.c:38
(gdb) list #--- let's see code around segfaulting instruction
10 int initfunc(int *array, int len) {
11
12 int i;
13
14 for(i=1; i <= len; i++) {
15 array[i] = i;
16 }
17 return 0;
18 }
19
(gdb) p array[0] #--- let's print out some values and see what's going on
Cannot access memory at address 0x0
#-- it looks like array is a bad address (0x0 is NULL)
(gdb) p array
$1 = (int *) 0x0
(gdb) frame 1 #--- let's see what main is passing to this funtion
#1 0x0804846e in main () at segfaulter.c:38
38 if(initfunc(arr, 100) != 0 ) {
(gdb) print arr #--- print out arr's value (what we pass to initfunc)
$2 = (int *) 0x0
#--- oops, we are passing NULL to initfunc...we forgot to initialize arr to point to valid memory
Keyboard shortcuts in gdb
gdb supports command line completion; by typing in a prefix you can
hit TAB and gdb will try to complete the command line for you.
Setting breakpoints in C++ code
One complication with gdb and C++ programs, is that you need to specify
methods and data members using the "classname::" prefix. In addition, you
often need to use a leading ' before a name for gdb to find the symbol,
and if methods are overloaded, you need to specify which method it is by
listing its full prototype (actually, if you hit TAB gdb will list all
possible matches for you and you can pick one of those).
(gdb) break 'BufMgr::pinPage(int, Page *&, int)'
This looks pretty icky, but really I just type break 'BufMgr::p
then hit TAB for automatic completion.
(gdb) break 'BufMgr:: <tab>
will list all methods of the BufMgr class, then you can just pick
from the list the method you want to put the breakpoint in.
gdb and make
Within gdb you can invoke "make" to rebuid your executable (assuming
that you have a makefile to build your program). This is a nice feature
in the case when you have many breakpoints set and do not want to exit gdb,
recompile, re-start gdb with the new a.out, and reset all the breakpoints.
However, keep in mind that modifying and recompiling your source code from
within gdb may result in your breakpoints not being where you think they
should be (adding/removing lines of source code can result in your
in your breakpoints no longer being where you want them to be in terms of
the new version of your source code). You can use the disable or delete
commands to disable or delete old breakpoints.
gdb Links
common gdb commands (from above)
example gdb sessions (from above)
GDB quick reference card
A very complete GDB reference
Using GDB within Emacs by Ali Erkan