Using GDB

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 

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
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.

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 

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.

你可能感兴趣的:(Tools)