gdb, inline source, and stepping through your code

I really like having inline source when using gdb. Code Complete, by Steve Mcconnell has an entire chapter explaining how you should proactively step through all code you write — and not just when you’re actively debugging an issue. Having followed this practice for a few years now, I can testify that it increases your productivity enormously. I simply can’t imagine not doing so before committing any code.

Inline source

Many users of gdb aren’t aware how it locates the source when stepping through your code. It can do this because the absolute paths to the source files are embedded in the object files — but, of course, you must first compile your source in debug mode using the -g option.

[philip@localhost inline-source]$ gcc -g test.c -o test
[philip@localhost inline-source]$ gdb test
GNU gdb (GDB) Fedora (7.0.1-37.fc12)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
Reading symbols from /home/philip/coding/inline-source/test...done.
(gdb) break main
Breakpoint 1 at 0x80483bd: file test.c, line 6.
(gdb) c
The program is not being run.
(gdb) run
Starting program: /home/philip/coding/inline-source/test
Breakpoint 1, main () at test.c:6
6 printf("Hello, world!n");
Missing separate debuginfos, use: debuginfo-install glibc-2.11.1-1.i686
(gdb) c
Hello, world!
Program exited normally.
(gdb) quit

Professionally I have worked with many systems that have a very small root file system, but often have other large partitions. While the compiled binaries will fit on the target system it’s often difficult to fit all the source — but the source was compiled on the root file system of my development machine. When stepping through the code on the target system gdb therefore won’t be able to find the source on the root file system of the target.

One easy way to work around this is to rsync over all the source to the large partition, and simply replicate the source file tree on the root partition but replace each leaf (i.e. each filename) with a symlink to a location on the large partition. And at this location should be the source file. I have many scripts like this — and they make heavy use of expect. The rsync options I use are shown below.

spawn rsync -e ssh -vltrSzDC --include "*.h" --include "*.c" --include "*.cc" --include "*/" --exclude "*" $dir/ $SSH_USERNAME@$appliance:$TMP_SRC_DIR/$dir/

Python and pdb

I have extended this practise of stepping through code to my python development. The python debugger works quite well, and its command syntax is (deliberately, I guess) very similar to gdb.

So if you don’t already, start stepping through your code as you write it. Don’t wait for that e-mail from Bugzilla.

Leave a Reply

Your email address will not be published. Required fields are marked *