The GNU Debugger Command (GDB) is a very useful debugging tool, widely used in the C environment.

So this helps us a lot, it even shows us the line causing the problem. Now we’ll create a core file to show how the latter one works, too. Note that # at the beginning of the line specifies that commands are run as root:

The -g compiler option is used to add debugging information to the executable (here a.out) for use by GDB. We’ll run it again using gdb , because the above code gives us a segmentation fault:

Let’s have a look at the former one on a simple program:

GDB can be run in two distinct ways:

Useful commands

Let’s see a common workflow, while using GDB:

$ gdb a.out # run with gdb debugger (gdb) break main # set up breakpoint at main() function Breakpoint 1 at 0x80483bc: file random.c, line 6. # this suspends the program # can also receive file name (break random.c:3) # or address (break *0x080483c5) (gdb) run # .. just run the thing Starting program: /home/andrei/a.out Breakpoint 1, main () at random.c:6 # it stops at first breakpoint 6 char *no_addr = 0; (gdb) next # execute next line, doesn't enter functions 7 *no_addr = random(); (gdb) step # like next, but enters functions random () at random.c:2 2 int r = 4; (gdb) next 3 return r; (gdb) print r # print values in decimal $1 = 4 (gdb) print /x # hexa $2 = 0x4 (gdb) print /o # octal $3 = 04 (gdb) print &r $4 = (int *) 0xbfffef5c (gdb) list # list source code 1 int random() { 2 int r = 4; 3 return r; 4 } 5 int main() { 6 char *no_addr = 0; 7 int r = random(); 8 *no_addr = r; 9 return 0; 10 } (gdb) break 8 # add breakpoint at line 8 Breakpoint 2 at 0x80483cb: file random.c, line 8. (gdb) continue # continue to next breakpoint Continuing. Breakpoint 2, main () at random.c:8 8 *no_addr = r; (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x080483d3 in main () at random.c:8 8 *no_addr = r; (gdb) backtrace # print stack backtrace; show trace of where you are # which functions you're in #0 0x080483d3 in main () at random.c:8 (gdb) quit

Now, some other thing you may find useful is to have the value of an expression get printed frequently (automatically, of course). You can do that with display expression . Take this sample code:

int main() { main() { int i, j = 0 ; i, j = for (i = 0 ; i < 10 ; i++) (i =; i 10 ; j += i * return 0 ; }

And run it in gdb :

(gdb) break main Breakpoint 1 at 0x804839a: file random2.c, line 2. (gdb) run Starting program: /home/andrei/a.out Breakpoint 1, main () at random2.c:2 2 int i, j = 0; (gdb) next 3 for (i = 0; i < 10; i++) (gdb) next 4 j += i * 10; (gdb) display i 1: i = 0 (gdb) display j 2: j = 0 (gdb) break 4 if i == 8 Breakpoint 2 at 0x80483aa: file random2.c, line 4. (gdb) continue Continuing. Breakpoint 2, main () at random2.c:4 4 j += i * 10; 2: j = 280 1: i = 8

This way you can see how your variables’ value change. To delete a display, use the number associated with it:

(gdb) delete display 2 (gdb) next 4 j += i * 10; 1: i = 3

One last trick worth mentioning in this initial GDB tutorial is setting up your ~/.gdbinit file. When GDB starts up, it looks for a file in the current user’s home directory called .gdbinit ; this file is used for simple configuration commands. The format is the following:

define <command> <code> end document <command> <help text> end

A simple example of .gdbinit :

andrei@sherlock:~$ cat .gdbinit define cls shell clear end document cls Clears the screen with a simple command. end define bpl info breakpoints end document bpl List breakpoints end

Now you can use cls to clear the screen in gdb, or you can find what breakpoints you’ve set:

(gdb) bpl Num Type Disp Enb Address What 1 breakpoint keep y 0x0804839a in main at random2.c:2 2 breakpoint keep y 0x080483aa in main at random2.c:4

You can also use .gdbinit inside your project’s directory to include commands used only for this project. It will be read when starting gdb in that directory and it overwrites the settings in ~/.gdbinit . You can add into it a few commands to be run when the gdb starts: commands like setting up the breakpoints and the values used with display commands.

Using the previous source code, we add the following .gdbinit file in the same directory:

b main r disp i disp j disp /x i disp

Now, we can run gdb :

$ gdb -q ./a.out Reading symbols from /tmp/a.out...done. Breakpoint 1 at 0x804839a: file 1.c, line 5. Breakpoint 1, main () at 1.c:5 5 int i, j = 0; 3: /x i = 0x0 2: j = 134513616 1: i = 0 (gdb) n 6 for (i = 0; i < 10; i++) 3: /x i = 0x0 2: j = 0 1: i = 0 (gdb) q

Observe the last disp in the .gdbinit file, used to display all expressions defined up to that point.

If you want to disable reading the .gdbinit files, pass a -n flag to gdb just like we passed -q above to strip the header with version info.

Final notes. CGDB is a curses front-end to GDB and is more friendly and coloured than GDB. Also, try this in GDB (I know this from Andrada Georgescu):

(gdb) b main Breakpoint 1 at 0x804839a: file random2.c, line 2. (gdb) r Starting program: /home/andrei/a.out Breakpoint 1, main () at random2.c:2 2 int i, j = 0; (gdb) - # add dash and enter

For more on GDB, check out this tutorial, 8 gdb tricks you should know.