gdb mini howto
Introduction
Debug information
gcc has a command line switch (-g) which will make gcc write debug informations into object files and executables. It is common practice in the free software community to compile projects with debug info, but strip it off when installing with "make install". Thus you'll usually see a big file size difference between the executables within the source tree and the installed ones, and using the executables from the source tree with gdb gives better results.
Analyzing a segfault
Most distributions have core dumps disabled by default, thus you'll have to reenable them first. "ulimit -c unlimited" will do that for the current shell and all processes started from it. Check the bash manpage if you want to know more about the ulimit command.
The next time some application crashes with a segfault you'll see that the message "Segmentation fault" changed to "Segmentation fault (core dumped)" and you'll find a file named "core" or "core.pid" in the current directory. Note: You need also write access for the current directory, otherwise that isn't going to happen.
Now it is time to start gdb to see what exactly happened. The first argument for gdb should be the executable of the crashed application, the second the core dump written due to the crash. gdb will read alot of informations and will great you with a "(gdb)" prompt when it is done. The most useful piece of information for a developer is a so called stacktrace. Typing "bt" at the prompt asks gdb to print one (which you can mail to the developer). With "quit" you'll leave gdb.
Other ways to use gdb
- bt
- print a stacktrace (as mentioned above).
- c
- continue running the application.
- print expression
- print the value of the specified expression. Can be used to inspect the value of certain variables for example, simply specify the variable name as expression
- quit
- quit gdb.
Advanced gdb debugging
More common gdb commands are:
- s
- single step though the application.
- break argument
- set breakpoints, i.e. make the application stop (and gdb give you a prompt) once it reaches some specific point, some function for example.
- watch expression
- set a watchpoint, i.e. stop if expression has changed. Can be used to catch the line of code which modifies some variable for example.
- help
- gdb online help. Go read there all the details, the scope of this
document ends just here :-)
BTW: a nice info manual for gdb is available too.
other useful debug tools
- electric fence
- malloc debugger, helps to catch typical memory management bugs like
accessing already freed memory, buffer overflows, ...
Comes as library which can either explicitly linked against the application or loaded via LD_PRELOAD. - strace
- print a log of all (or selected) system calls some application
performes.
One common programming mistake is missing error handling, not checking the return value of system calls for example. Instead of notifying the user with a message like "opening file foo failed with error bar" applications simply assume that opening the file worked and just crash later if it didn't. That kind of bug often can easily be found with strace because you'll see the system call return values in the strace log.
Of course strace is useful for alot of other purposes too.