Как устранить утечку памяти при использовании сгенерированного кода gdbus-codegen?

У меня есть интерфейс, описанный в формате DBus Introspection XML:

<!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>

Я запускаю gdbus-codegen следующим образом:

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

Я использую такой код:

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

    return 0;
}

Но в итоге приложение пропускает сигнал, сгенерированный в dbus_foo_default_init(), который выглядит так:

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);

}

Мой вопрос:

Как выполнить очистку после использования сгенерированного кода gdbus-codegen?


person anorm    schedule 06.02.2015    source источник
comment
Не совсем ответ, но ссылки все же могут помочь: нет общедоступного API для отмены регистрации сигнала. Сигналы автоматически выпускаются, когда связанный с ними тип завершен .   -  person Phillip    schedule 09.02.2015
comment
Значит, при вызове g_object_unref(skeleton) сигнал тоже должен был быть уничтожен? Кажется, это не так. Если только я не использую его неправильно. Я проверю еще раз, чтобы убедиться, что скелетный объект больше нигде не зарегистрирован и нет дополнительных утечек памяти.   -  person anorm    schedule 09.02.2015
comment
Я повторил тест с main(), состоящим из только dbus_foo_skeleton_new() и g_object_unref(foo). Он по-прежнему протекает, и нет других утечек, кроме сигнала.   -  person anorm    schedule 09.02.2015
comment
Единственное, что мне приходит на ум, это то, что финализаторы вызываются только для динамических интерфейсов в соответствии с документацией, но сгенерированный код объявляет DbusFooIface (на котором определен сигнал) статически. (см. также. )   -  person Phillip    schedule 09.02.2015
comment
Я не думаю, что вы должны убирать это. Сигнал принадлежит интерфейсу, который отличается от любого конкретного экземпляра объекта, реализующего этот интерфейс. Хорошо это или плохо, но классы и интерфейсы регистрируются в системе типов GObject и освобождаются только в конце программы.   -  person ptomato    schedule 11.02.2015
comment
Вы пытались проверить утечки памяти с помощью valgrind?   -  person BЈовић    schedule 29.04.2015


Ответы (1)


Я подозреваю, что вы обнаружите это, если запустите свою программу под valgrind, используя последний файл подавления GLib (версия которого установлена ​​в /usr/share/glib-2.0/valgrind/ в большинстве дистрибутивов Linux), утечки нет. Как сказал @ptomato в комментарии выше, сигналы считаются данными типа, и GObject никогда не освобождает их (кроме динамически зарегистрированных типов). Данные типа выделяются один раз (при первом использовании) и никогда не освобождаются. Не беспокойтесь об этом.

person Philip Withnall    schedule 03.10.2017
comment
Я исправил ссылку и указал путь установки, спасибо - person Philip Withnall; 16.07.2021
comment
Дополнительная информация о файлах подавления для valgrind: wiki.gnome.org/Valgrind - person DarkTrick; 19.07.2021