gdb
Exercisesgdb
is the GNU Debugger, and can be a useful tool for analyzing
problems with your code. This page gives a simple set of
exercises to help you get acquianted with the debugger and it's
functionality. For more information consult the man page ('man gdb'),
or view the
online manual.
Login to attu. (The behavior of the (buggy) program used as an example can be slightly different under cygwin, and might not match what follows.
gdb
behaves mostly the same under the two systems, though. )Create a directory, copy the test program into it, and
cd
into that directory:$ mkdir ~/gdbTest $ cd !$ $ cp /cse/courses/cse303/04au/gdbExample.c .It appears that the default behavior onattu
is to not create core dump files. Since we want them, turn them on:$ ulimit -c unlimited
Take a brief look at the source file - it's a simple C program. Now, try executing the following commands:
$ gcc gdbExample.c $ ./a.out Segmentation fault (core dumped)The program crashes. This is probably not a good sign - let's try taking a closer look at it:
$ gdb a.out (gdb) core core.<tab>enter>
gdb
loads up the core file, which is actually the state of the memory of our program at the time it crashed. We can askgdb
to tell us what functions were being called at the time of the crash using 'bt'(gdb) bt #0 0x080483cf in main ()It looks like we crashed in main() - lets try to see where exactly this happened:
(gdb) list No symbol table is loaded. Use the "file" command.This isn't very useful information. Why is gdb being so recalcitrant? We address that next. For now, just quit
gdb
and clean up:(gdb) q $ rm core.*
gdb
wasn't very cooperative so far because it doesn't have enough information - it doesn't have a way to relate the executable code (a.out
) to the source that produced it (gdbExample.c
). It turns out the way to relate those two is to embed debugging information in the executable. That's done using the-g
switch when compiling:$ gcc -ggdb gdbExample.c $ ./a.out Segmentation fault(core dumped) $ gdb a.out (gdb) core core.<tab><tab><enter> [elided lines...] #0 0x080483cf in main (argc=1008, argv=0x3f1) at gdbExample.c:9 9 x[i] = i;Now this is better -
gdb
has actually located the exact line in our source file which caused the crash! What can we do with this? Let's see what the variables look like:(gdb) print i $1 = 1544 (gdb) print x[10] $2 = 10 (gdb) print x[i] Cannot access memory at address 0xc0000000(We're not sure what that means, but it can't be good.)What did the code nearby look like?
(gdb) list 4 int main(int argc, char* argv[]) { 5 int i, j, k; 6 int x[1000]; 7 8 for(i = 0; i < 10000; ++i){ 9 x[i] = i; 10 } 11 12 printf("Enter integer: "); 13 scanf("%d", k);Oops. The array
x
is only 1/10th the size we meant it to be. Fix it (by correcting its size to 10000). (Exitgdb
.)
gdb
We're going to compile and run the corrected program, but this time we're going to run inside ofgdb
:$ gcc -ggdb gdbExample.c $ gdb a.out [elided lines...]Now set a breakpoint, and start execution:
(gdb) break gdbExample.c:8 Breakpoint 1 at 0x80483b7: file gdbExample.c, line 8. (gdb) run Starting program: /homes/iws/zahorjan/test/a.out Breakpoint 1, main (argc=1, argv=0xbfffdea4) at gdbExample.c:8 8 for(i = 0; i < 10000; ++i){Execution has stopped at the line shown. We can single step:(gdb) step 9 x[i] = i; (gdb) step 8 for(i = 0; i < 10000; ++i){ (gdb) step 9 x[i] = i; (gdb) step 8 for(i = 0; i < 10000; ++i){Since this will take a while with a loop running 10000 times, let's continue on:
(gdb) break gdbExample.c:12 Breakpoint 2 at 0x80483dd: file gdbExample.c, line 12. (gdb) continue Continuing. Breakpoint 2, main (argc=1, argv=0xbfffdea4) at gdbExample.c:12 12 printf("Enter integer: ");Okay, you have the idea of howgdb
works. Let's just continue program execution:(gdb) continue Continuing. Enter integer in 0..9999: 9998 Program received signal SIGSEGV, Segmentation fault. 0x0804842d in tester (c=0xbfff59c0, k=1187688412) at gdbExample.c:19 19 printf("x[%d] = %d\n", k, c[k]); (gdb) bt #0 0x0804842d in tester (c=0xbfff59c0, k=1187688412) at gdbExample.c:19 #1 0x08048412 in main (argc=1, argv=0xbffff6a4) at gdbExample.c:15Well, there's yet another bug. No problem, though, at this point you know enough about
gdb
to find it easily.
- Try compiling
gdbExample.c
with the-Wall
switch. What does it tell you? (Is it useful? surprising?)- Try writing a program with multiple functions, one of which causes the program to crash. Investigate the usage of the 'bt', 'up' and 'down' commands provided by
gdb
.