GObject: debug reference counting

Hi,

I’ve an issue with a widget not being disposed/finalized after I unparent() it, despite not keeping any reference on the application side.

Are there any tips or debug features to help figuring out what is still holding a reference?

FWIW, instead of a conditional breakpoint on g_object_ref, as you’re suggesting, it is much faster (g_object_ref is called a lot!) to set a watchpoint to the object’s ref_count, like this:

(gdb) watch -l ((GObject *) window)->ref_count
Hardware watchpoint 4: -location ((GObject *) window)->ref_count

(gdb) c

Thread 1 "gtk4-demo" hit Hardware watchpoint 4: -location ((GObject *) window)->ref_count

Old value = 1
New value = 2
0x00007ffff724f74c in toggle_refs_check_and_ref_or_deref (
    object=0x555555e1fa90 [GtkWindow], is_ref=1, old_ref=<synthetic pointer>, 
    toggle_notify=0x7fffffffc6b8, toggle_data=0x7fffffffc6b0)
    at ../gobject/gobject.c:4356
4356	  success = g_atomic_int_compare_and_exchange_full ((int *) &object->ref_count,
(gdb) bt
#0  0x00007ffff724f74c in toggle_refs_check_and_ref_or_deref
    (object=0x555555e1fa90 [GtkWindow], is_ref=1, old_ref=<synthetic pointer>, toggle_notify=0x7fffffffc6b8, toggle_data=0x7fffffffc6b0)
    at ../gobject/gobject.c:4356
#1  object_ref
    (object=object@entry=0x555555e1fa90 [GtkWindow], out_toggle_notify=out_toggle_notify@entry=0x7fffffffc740, out_toggle_data=out_toggle_data@entry=0x7fffffffc738) at ../gobject/gobject.c:4622
#2  0x00007ffff72513dc in g_object_ref (_object=_object@entry=0x555555e1fa90)
    at ../gobject/gobject.c:4664

That did not work when I wrote that article. It would be nice if it works now :smiley:

Thanks!

Yup, that trick was mentioned in the comments section of the 1st link too. It’s probably the simplest and portable solution in the list.

Worked fine on my side, and I could finally find the culprit holding a circular reference :partying_face:

For the record, I configure glib with:

meson setup _build --debug --optimization=g