1

I have an interface described in DBus Introspection XML format:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
                      "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="com.example.foo">
    <method name="Bar" />
  </interface>
</node>

I run gdbus-codegen like this:

gdbus-codegen --interface-prefix=com.example --generate-c-code=foo-dbus --c-namespace=Dbus foo.xml

I use the code like this:

int main()
{
    DbusFoo * skeleton = dbus_foo_skeleton_new();
    g_object_unref(skeleton);

    return 0;
}

But the application ends up leaking a signal generated in dbus_foo_default_init() which looks like this:

static void
dbus_foo_default_init (DbusFooIface *iface)
{
  /* GObject signals for incoming D-Bus method calls: */
  /**
   * DbusFoo::handle-bar:
   * @object: A #DbusFoo.
   * @invocation: A #GDBusMethodInvocation.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-com-example-foo.Bar">Bar()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call dbus_foo_complete_bar() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-bar",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (DbusFooIface, handle_bar),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    1,
    G_TYPE_DBUS_METHOD_INVOCATION);

}

My question:

How do I clean up after using the gdbus-codegen generated code?

anorm
  • 2,255
  • 1
  • 19
  • 38
  • 2
    Not really an answer, but the links might still help: [There is no public API to unregister a signal](https://github.com/GNOME/glib/blob/6a97275c4507e08b66fdeb4bb054bb8f78096f14/gobject/gsignal.c#L811). Signals are [automatically released when their associated type is finalized](https://github.com/GNOME/glib/blob/1cf7f5a2400ee9f4140e5c5bfab60e536bdabf14/gobject/gobject.c#L425). – Phillip Feb 09 '15 at 13:41
  • So, when calling `g_object_unref(skeleton)`, the signal should have been destroyed as well? It seems it doesn't. Unless I'm using it wrong. I'll check again to verify that the skeleton object isn't registered anywhere else and that there are no additional memory leaks. – anorm Feb 09 '15 at 13:50
  • I reran the test with a `main()` consisting of *only* `dbus_foo_skeleton_new()` and a `g_object_unref(foo)`. It still leaks and there are no other leaking records than the signal. – anorm Feb 09 '15 at 13:59
  • The only other thing that comes to my mind is that [finalizers are only called for dynamic interfaces according to the docs](https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#g-type-default-interface-unref), but the generated code declares the DbusFooIface (on which the signal is defined) statically. ([See also](https://developer.gnome.org/gobject/stable/gtype-instantiable-classed.html#gtype-init-fini-table).) – Phillip Feb 09 '15 at 16:06
  • 4
    I don't think you _should_ clean this up. The signal is owned by the interface, which is distinct from any particular object instance that implements that interface. For better or for worse, classes and interfaces are registered in the GObject type system and only freed at program end. – ptomato Feb 11 '15 at 08:02
  • Did you try to check the memory leaks with valgrind? – BЈовић Apr 29 '15 at 13:10

1 Answers1

1

I suspect you will find that, if you run your program under valgrind using the latest GLib suppressions file (a version of which is installed in /usr/share/glib-2.0/valgrind/ on most Linux distros), there is no leak. As @ptomato said in a comment above, signals count as type data, and GObject never frees that (apart from for dynamically registered types). Type data is allocated once (when first used) and never freed. Don’t worry about it.

Philip Withnall
  • 5,293
  • 14
  • 28