GDB HOWTO

               An Introduction to Your Newest Best Friend, gdb


It's 2am, your program is due at 8am and it's still seg faulting.  You've been
staring at the code for hours and can't find what's wrong with the darn thing.
Sane people are at home in bed, I.E.'s are out at the bars, and you're stuck 
in LWSN working on cs240.

Sound familiar?

Well, there's a cool little tool called "gdb" that can help you with this,
and it's installed on pretty much every UNIX machine everywhere.  It can show 
you the exact line that caused your program to die, which is a lot faster
than putting printf's all over the place.

gdb is the GNU Debugger.  A debugger is a program that helps you find errors in
your programs.  This is a very brief look at gdb, there's a lot of good
help for it online that you can investigate further.

This may be the most useful thing you learn in cs240, no kidding.  Please
read through this email and run through the dumb little examples.  They're 
simple, but if you learn how it works, this may save you TONS of time later 
on.  I use gdb at least a couple times a week while writing code (and 
grading yours).  C'mon, everybody's doing it...


Let's say that you have a program in "badcode.c":
   #include 
   int main(void)
   {
      int *p;
      free(p);
      return(0);
   }

(okay, that's not too useful, but it'll serve our purposes for now)


You compile the program and run it...

   [cs240]$ gcc -Wall badcode.c 
   [cs240]$ a.out
   Segmentation fault (core dumped)
   [cs240]$ 

Shoot!  Now what?  To use gdb you must use the gcc "-g" flag.  This 
automatically adds debugging information to your code.  So, compile your 
code again and then run gdb with your program:

   [cs240]$ gcc -g -Wall badcode.c 
   [cs240]$ gdb a.out

gdb starts up:

   GNU gdb 4.17.0.11 with Linux support
   Copyright 1998 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 "i386-redhat-linux"...
   (gdb) 

You can type "help" for information on how to use gdb.  Useful commands
to know are list, print, break, run, continue, next and step.  Let's just run
the program and see what happens.

   (gdb) run
   Starting program: /home/svec/cs240/a.out 
   
   Program received signal SIGSEGV, Segmentation fault.
   0x400714de in __libc_free (mem=0x8049460) at malloc.c:2921
   malloc.c:2921: No such file or directory.
   (gdb) 

Of course, it seg faults, bummer.  Note that gdb complains that it can't find
malloc.c - this is because malloc.c was compiled by the system administrator,
and was not compiled with the "-g" option, so no debugging information is
available from malloc.c.  This is not a problem for us.  (We're that good.)

Use the "backtrace" (or just "bt") command to find out where your program
was when it died:

   (gdb) backtrace
   #0  0x400714de in __libc_free (mem=0x8049460) at malloc.c:2921
   #1  0x80483df in main () at badcode.c:5
   #2  0x40030cb3 in __libc_start_main (main=0x80483d0 
, argc=1, argv=0xbffffa64, init=0x8048298 <_init>, fini=0x804841c <_fini>, rtld_fini=0x4000a350 <_dl_fini>, stack_end=0xbffffa5c) at ../sysdeps/generic/libc-start.c:78 This shows us that it died in main(), at line 5 of badcode.c. If we look at line 5 in badcode.c we find that we're trying to free memory that we never malloc'ed - a very common cause of seg faults. So now you can go and fix your code and finally get some sleep. Or if it's near enough to Dead Week you can get back to watching Bond on TNT. Now let's look at a more complicated example of using gdb. Let's say that you have a program in "morecode.c": int add_2(int value) { int retval; retval = value + 2; return(retval); } int main(void) { int A, B; A = 42; B = add_2(A); return(B); } Compile the code with the "-g" flag and we'll run gdb through its paces. [cs240]$ gcc -g -Wall morecode.c [cs240]$ gdb a.out gdb (and most debuggers) allow you to set breakpoints in the code - the program will automatically "pause" execution when it reaches a breakpoint. Breakpoints can be set at source code lines or function calls. To set a breakpoint at the main() function you can type "break main". (gdb) break main Breakpoint 1 at 0x804843e: file morecode.c, line 14. (gdb) You could have also typed "break 14" if you knew the line number you wanted to break on. Type "run" and the program will run until it hits a breakpoint. (gdb) run Starting program: /home/svec/cs240/a.out Breakpoint 1, main () at morecode.c:14 14 A = 42; (gdb) Use the command "list" to print out the source code with line numbers. (gdb) list 9 10 int main(void) 11 { 12 int A, B; 13 14 A = 42; 15 16 B = add_2(A); 17 18 return(B); (gdb) To step through the program you can use "next" and "step", or "n" and "s". Try stepping through this program using "next" and "step" until the program quits. Also try "continue". Also try "print A" and "print B" to see the values of these variables. Make sure you read the help on all these commands (like "help print") so you understand them. Now you know how to use gdb! You can run gdb on pretty much any UNIX machine in the world. You may also want to take a look at 'ddd' - it's a graphical version of gdb you can use if you're logged in at a graphical terminal. Don't forget the "help" command within gdb, or just type "man gdb" from any UNIX prompt to get more info. I hope that proves useful, I think it will. -svec