Initialize a GDB debug session
Published on 2010-04-23
I decided to write down my bug-hunting method for “C family” applicatons in order to have it in one place. Mainly since there are a lot of applications with “gotchas” and having a more mechanized approach doesn’t hurt my brain just as much.
So how do we do it? First and foremost you must install a version of the binary with a complete symbol table. It is the symbol table which makes the debugger “aware” of where in the source code you are currently executing. For FreeBSD this is extremely simple, just enable debugging in the port:
make WITH_DEBUG=yes install clean
Since FreeBSD uses GCC, and not clang, it is telling the port makefile to enable the “-g” argument for gcc. This tells gcc to add and keep symbols during compilation/linking. Conversely the “-s” argument removes or strips the binary of symbols.
Next remind yourself that the actual file you are executing need not be a binary but a script which sets up an initial environment and then forks the real process. It is generally easier to just run gdb directly and then attach the process in mid flight into gdb:
application &
pgrep app-name > app-name.pid
Next thing to do is to attach the process into gdb:
cat app-name.pid
3375
gdb
... # a few lines of output
(gdb) attach 3375
... # some more lines of output
(gdb) handle SIGPWR nostop noprint
(gdb) handle SIGXCPU nostop noprint
(gdb) handle SIG33 nostop noprint
The “handle” SIG* lines are there to tell gdb to ignore some realtime events, or just signals, which can be generated from different applications (especially if they are garbage collected).