Secret GObject Fu

Whilst trying to find a nasty reference counting problem in my code, Alex told me about the g_trap_object_ref variable in debug builds of GObject. Basically, when a debug version of GObject refs or unrefs an object, it is compared to the pointer in g_trap_object_ref, and if it matches it causes a breakpoint.

Very useful, I can do this:

$ libtool gdb ./EDataBookFactory...
[line 191 is known to be after my object has been created]
(gdb) break e-data-book-factory.c:191
(gdb) run
Breakpoint 1, impl_BookFactory_getBook (...) at e-data-book-factory.c:191
[book is the pointer to the new object]
(gdb) set g_trap_object_ref=book
(gdb) cont

Program received signal SIGTRAP, Trace/breakpoint trap.
0xb7e74869 in IA__g_object_ref (_object=0x806fd88) at gobject.c:1672
1672        G_BREAKPOINT ();
(gdb) bt
#0  0xb7e74869 in IA__g_object_ref (...) at gobject.c:1672
#1  0xb7e751a1 in IA__g_value_set_object (...) at gobject.c:1907
#2  0xb7e52f74 in invoke_object_method (...) at dbus-gobject.c:848

Here ew can see that invoke_object_method in dbus-gobject.c is incrementing the reference count on my object via a GValue. A quick peek at the code reveals that this reference is not being released in some situations, which I fixed and now my objects are being disposed as expected.

I hope this is a documented feature, and if not I'll add a comment about it when CVS is back. To make my life complete, if anyone knows a way to make gdb print the stack and continue when it breaks, please tell me!

Update: the most excellent Daniel Stone pointed out the commands command, which lets you run arbitary commands when a breakpoint is reached. Now all I need to know is how to tie commands to a SIGTRAP...

NP: Sounds From The Verve Hi-Fi, Thievery Corporation

11:02 Wednesday, 29 Jun 2005 [#] [computers] ( comments)