// stap -DMAXMAPENTRIES=65536 --ldd ibusrefs.stp -c "ibus-daemon -vx" -d /usr/bin/ibus-daemon global ibusobjects; global ibusroottypename = "IBusProxy"; global ibusroottype; global parentgtypes; global verbose = 0; function is_a:long (gtype:long, is_a_gtype:long) { parent_gtype = parentgtypes[gtype]; while (parent_gtype != 0) { if (parent_gtype == is_a_gtype) return 1; parent_gtype = parentgtypes[parent_gtype]; } return 0; } probe gobject.type_new { if (name == ibusroottypename) ibusroottype = gtype; else parentgtypes[gtype] = parent_gtype; } function indent_ubacktrace () { bt = sprint_ubacktrace () line = tokenize (bt, "\n"); while (line != "") { printf (" %s\n", line); line = tokenize ("", "\n"); } } probe gobject.object_new { if (is_a (gtype, ibusroottype)) { if (verbose) { printf ("%d %s %p new (0 -> 1)\n", pid (), type, object); indent_ubacktrace (); printf ("\n"); } ibusobjects[pid(), type, object]++; } } probe gobject.object_ref { if (is_a (gtype, ibusroottype)) { if (verbose) { printf ("%d %s %p ref (%u -> %u)\n", pid (), type, object, old_refcount, refcount); indent_ubacktrace (); printf ("\n"); } ibusobjects[pid(), type, object] = refcount; } } probe gobject.object_unref { if (is_a (gtype, ibusroottype)) { if (verbose) { printf ("%d %s %p unref (%u -> %u)\n", pid (), type, object, old_refcount, refcount); indent_ubacktrace (); printf ("\n"); } ibusobjects[pid(), type, object] = refcount; } } probe gobject.object_finalize { if (is_a (gtype, ibusroottype)) { if (verbose) { printf ("%d %s %p finalize (X -> 0)\n", pid (), type, object); indent_ubacktrace (); printf ("\n"); } ibusobjects[pid(), type, object] = 0; } } probe end { printf ("Objects still alive:\n"); foreach ([p+, t, o] in ibusobjects) { r = ibusobjects[p,t,o]; if (r > 0) printf ("%d %s %p %d\n", p, t, o, r); } }