GNOME Bugzilla – Bug 676498
Reference counting bug in signal handling causes hang with GApplication 'command-line' usage
Last modified: 2013-02-04 10:29:51 UTC
With the GApplication class, developers should add a handler
for the 'command-line' signal, or override the 'command_line'
class method in order to have ARGV handling done in the primary
instance. Any secondary instances will send their CLI args to
the primary instance and then exit once they have been processed
In python such code would look like this:
from gi.repository import Gio
from gi.repository import Gtk
def do_command_line(app, cmdline):
win = Gtk.Window(Gtk.WindowType.TOPLEVEL)
app = Gtk.Application(application_id="org.gtk.TestApplication",
status = app.run(sys.argv)
The first time this code is run, the primary instance
will acquire that application ID on DBus and popup a window.
Any further attempts to run this script (ie secondary app
instances), should cause the 'do_command_line' method in
the primary instance to be invoked via DBus, and the
non-primary instance should then exit.
When running this Python example above, the 'CommandLine'
method on org.gtk.Application is invoked via DBus:
method call sender=:1.1632 -> dest=org.gtk.TestApplication serial=5 path=/org/gtk/TestApplication; interface=org.gtk.Application; member=CommandLine
object path "/org/gtk/Application/CommandLine"
array of bytes [
2e 2f 67 00
variant array of bytes [
2f 68 6f 6d 65 2f 62 65 72 72 61 6e 67 65 00
There is *never* any 'method return' sent from the primary
instance for this invocation though. ie, you would expect
to see the following from dbus-monitor:
method return sender=:1.1630 -> dest=:1.1632 reply_serial=5
This DBus code is handled in GIO by the following method
g_application_impl_method_call (from gapplicationimpl-dbus.c)
For the 'Activate' and 'Open' methods it directly calls
'g_dbus_method_invocation_return_value' to send the DBus reply.
For the 'CommandLine' method, however, the reply is sent
indirectly when the g_dbus_command_line_finalize method is called.
With this python example, the GApplicationCommandLine object
never appears to be finalized. Single-stepping over
g_application_impl_method_call with GDB shows that the reference
count on the GApplicationCommandLine instance is '2' immediately
after the signal has been emitted. ie
g_signal_emit_by_name (impl->app, "command-line", cmdline, &status);
has leaked 1 reference on GApplicationCommandLine.
I also wrote the previous example in C:
static void hide(GtkWindow *win, GtkApplication *app)
command_line (GtkApplication *app,
GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gchar *title = g_strdup_printf("WIndow in process %d", getpid());
g_signal_connect(win, "delete-event", G_CALLBACK(hide), app);
main (int argc, char **argv)
app = gtk_application_new ("org.gtk.TestApplication",
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
status = g_application_run (G_APPLICATION(app), argc, argv);
With this example, everything works fine and the
GApplicationCommandLine instance is finalized. Thus
I infer that the PyGObject bindings are causing a
reference count leak on the GApplicationCommandLine
instance when emitting the 'command-line' signal
You can mix-and-match these two demo programs
- Primary instance: Python, secondary instance C -> secondary instance hangs waiting for dbus reply
- Primary instance: Python, secondary instance Python -> secondary instance hangs waiting for dbus reply
- Primary instance: C, secondary instance C -> secondary instance completes & exits
- Primary instance: C, secondary instance Python -> secondary instance completes & exits
which again points to the PyGObject code run in the primary instance being at fault.
This behaviour is all tested with the following version:
This behaviour prevents usage of the GApplication class for command line handling in Python
*** Bug 679053 has been marked as a duplicate of this bug. ***
I hit this too. See my testcase in bug 679053
I am also experiencing this in GottenGeography, but my app is single-instance anyway, so the hanged secondary instances aren't a huge problem for me: the key thing is that secondary instances do successfully communicate the commandline args to the primary instance, unlike with HANDLE_OPEN...
Created attachment 220445 [details]
Another minimal sample
I just hit this too in Onboard. As soon as the application's flags include Gio.ApplicationFlags.HANDLES_COMMAND_LINE, secondary instances get stuck in the D-Bus call to /org/gtk/Application/CommandLine.
1. run sample in one terminal
2. run sample in a second terminal
-> should exit immediately,
but hangs instead until primary instance exits
Still seeing the same problem in gnome 3.6.2 - any updates?
I am no longer able to reproduce this using either the test provided by John in bug 679053 or the one from marmuta. A lot of work has gone on recently to cleanup reference count bugs and this was most likely fixed by bug 675726.