I present a quick "howto" on using GDB to debug programs in a UNIX environment. Your situation: You have a program which crashes and makes a core file. You want to find out why it's crashing, exactly.
crash.c
#includeint main(void) { char * pointer; printf("Hello, world.\n"); pointer = (char *)-1; printf("The pointer points to this string: %s\n", pointer); return 0; }
It is compiled with the -g
argument to gcc
:
$ gcc -o crash -g crash.c $ ./crash Hello, world. Bus error (core dumped) $ ls -l total 328 -rwxr-xr-x 1 mikeg users 6025 Jan 30 13:35 crash -rw-r--r-- 1 mikeg users 185 Jan 30 13:34 crash.c -rw------- 1 mikeg users 311296 Jan 30 13:35 crash.core
The crash.core
file is what we're interested in.
Now we launch GDB and ask it to inspect the crash.core
file:
$ gdb crash crash.core GNU gdb 6.1.1 [FreeBSD] Copyright 2004 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-marcel-freebsd"... Core was generated by `crash'. Program terminated with signal 10, Bus error. Reading symbols from /lib/libc.so.5...done. Loaded symbols for /lib/libc.so.5 Reading symbols from /libexec/ld-elf.so.1...done. Loaded symbols for /libexec/ld-elf.so.1 #0 0x28120bc5 in __vfprintf () from /lib/libc.so.5 (gdb)
This tells us that the program terminated with signal 10, "Bus error"
, but we already knew that. GDB has captured the state of the program (by reading the core file) and tells us in the last line before the (gdb)
prompt where in the stack of recently called functions it finds itself -- right before the crash. At the (gdb)
prompt, we can enter commands. So let's look at the recently called functions:
(gdb) backtrace #0 0x28120bc5 in __vfprintf () from /lib/libc.so.5 #1 0x2811f513 in vfprintf () from /lib/libc.so.5 #2 0x2810c173 in printf () from /lib/libc.so.5 #3 0x0804856f in main () at crash.c:8
The backtrace command shows us all the "frames" that the program has been in. Here we see that most recently (frame 0), we visited __vfprintf
which is part of libc
, the standard C library on a UNIX system. This was called by vfprintf()
which was in turn called by printf()
, both also part of libc
. printf
was called by main()
in program crash.c
on line 8. Now we're getting somewhere!
We can inspect the state of local and static variables in the currently selected frame. By default, we're in frame 0. We really want to be in frame 3. So we switch frames, and ask GDB for information about local variables with the info
command like so:
(gdb) frame 3 #3 0x0804856f in main () at crash.c:8 8 printf("The pointer points to this string: %s\n", pointer); (gdb) info locals pointer = 0xffffffff
Now we know the cause of our problems. The variable pointer
points at memory address 0xffffffff
which GDB informs us is out of bounds. This is why printf
cannot cope with it. And that's why our program crashes.