Posted on January 11, 2008 by rodney
Tags: gnome
Emacs GDB screenshot

Here is an easy way to setup GDB to step through the GTK+ source code if you’re using the Debian (or Ubuntu) -dbg packages.

First thing to do, if you haven’t already done it, is to install the relevant debug packages. gnome-dbg is a metapackage which depends on a few other GNOME debug packages. Install it if you have enough disk space. If you’re like me and can’t spare the GBs then install only the necessary dependencies. In my case: gnome-panel-dbg libglib2.0-0-dbg libgtk2.0-0-dbg.

The -dbg packages put a tree of unstripped shared libraries in /usr/lib/debug. Unstripped objects contain symbol definitions (e.g. function names and their addresses) and debugging information (i.e. a mapping from instruction addresses to source code line numbers).

At this point you already have some useful information. When you debug your app in GDB you will notice that GDB reads symbols from the objects in /usr/lib/debug corresponding to the ones in /usr/lib. So when you look at the backtrace, function names will appear instead of something like this: #3 0x0f09ad50 in ?? () from /usr/lib/ However it would be nice to be able to trace through the source code.

The source code corresponding to a library is easy enough to get if you’re using Debian. You just need somewhere to put it. I have mine in ~/dev/pkg. So:

$ cd ~/dev/pkg $ apt-get source gnome-panel-dbg libglib2.0-0-dbg libgtk2.0-0-dbg

If you try going up your backtrace in GDB and stepping through the GTK+ code you will see no code and a message like this:

gtk_widget_event_internal (widget=0x100ca420, event=0x10190ee8) at /build/buildd/gtk+2.0-2.12.3/gtk/gtkwidget.c:4677
4677	/build/buildd/gtk+2.0-2.12.3/gtk/gtkwidget.c: No such file or directory.
	in /build/buildd/gtk+2.0-2.12.3/gtk/gtkwidget.c

The directory /build/buildd is the directory from which your GTK+ was built, when it was built on some other unknown machine. This will vary depending on the distribution (Debian or Ubuntu), the architecture, the package, and whoever happens to be the package maintainer. If you built the GTK+ package yourself it would be different. Sometimes the filename referred to is not absolute, e.g. this is the case for libpanel-applet.

Obviously, GDB must be told where to find the code. The GDB manual describes the possibilities available to you.

Absolute filenames like /build/buildd or /scratch/build-area

In this case, the easiest way is to create a source path substitution rule like this:

set substitute-path /build/buildd /home/rodney/dev/pkg

Change /build/buildd to whatever directory the debug symbols point to.

Change the underlined path to the place where you ran the apt-get source command.

No path in filename

If the message looks like this:
#5  0x00007f0521248624 in panel_applet_factory_main_closure (
    iid=0x404b74 "OAFIID:PanelVisApplet_Factory", 
    applet_type=, closure=)
    at panel-applet.c:1754
1754	panel-applet.c: No such file or directory.
	in panel-applet.c

i.e. gdb is looking for a file in the current directory, then find where the sources are.

$ find ~/dev/pkg -name panel-applet.c -printf ‘%h’ /home/rodney/dev/pkg/gnome-panel-2.24.2/libpanel-applet

And then use the dir command in gdb.

dir /home/rodney/dev/pkg/gnome-panel-2.24.2/libpanel-applet


Put these commands in your ~/.gdbinit and you will never have to think about it again… until someone upgrades the library.

Library upgrades

When the library packages are upgraded, the paths with become invalid, because they have the version in them. In this case, you will need to re-run the apt-get source command to retrieve the source code which matches your library version, then update your ~/.gdbinit. Alternatively, you could keep the old source code and add extra substitution rules to point GDB to the old code. However I don’t recommend this practice because the debugger will appear to act strange if the source code is too different and the line numbers don’t match up. A nasty surprise like that is the last thing you need when you’re up at 2AM debugging something.