Using GDB
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.
Our program, crash.c
#include <stdio.h>
int 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
-rw------- 1 xxx 57344 8月 25 15:42 core.7886
-rwxrwxr-x 1 xxx 22234 8月 25 15:42 crash
-rw-rw-r-- 1 xxx 182 8月 25 15:42 crash.c
-rwxrwxr-x 1 xxx14350 8月 25 15:42 crash-g
The crash.core
file is what we're interested in.
Enter GDB
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 <Address 0xffffffff out of bounds>
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.