GNOME Bugzilla – Bug 655664
gdbus should not abort if no dbus session is available
Last modified: 2011-08-01 16:10:07 UTC
When gdbus tries to make a connection via g_bus_get_sync(), and dbus can't be reached (because it isn't running), the application fails to start. This is not good, because these applications can run without dbus (e.g. firefox and gimp). Running without dbus is better than not running at all. gconf up until 2.28.x was not affected by this (maybe because it didn't use gdbus). The new behavior is a regression. From what I've found out, this is because the function get_uninitialized_connection() in gdbusconnection.c sets the exit-on-close property to true. When the g_bus_get_sync() tries to initialize the connection, and initialization fails, the application will be terminated because exit-on-close is enabled. I think exit-on-close should come into effect only after the connection has been successfully made.
Created attachment 192939 [details] [review] Simplistic patch against glib 2.27.2 Attaching a simplistic patch that enables applications to run without available dbus session again. The patch is against glib 2.72.2 and depends on the patch in bug #635694.
This is not a GDBus problem - it's a problem with the app (or a library it uses) that is using GDBus. In particular, g_bus_get() (including its sync version) returns NULL if no connection could be established. The fix needs to go in your app or library. Closing.
The apps are gimp and firefox (actually iceweasel). Can I quote you on this when reporting the bugs to the gimp and firefox projects?
(In reply to comment #3) > The apps are gimp and firefox (actually iceweasel). > > Can I quote you on this when reporting the bugs to the gimp and firefox > projects? Certainly. The docs are also more or less clear on it, e.g. http://developer.gnome.org/gio/unstable/GDBusConnection.html#g-bus-get-sync says that NULL is a valid return value. Btw, now that I think of it, there might be a problem with the reference implementation of the bus daemon (dbus-daemon-1) insofar that if you connect with a different UID then negotiation will work (e.g. the bus replies with the 'OK' command in the negotiation phase) but the bus daemon will disconnect you immediately... and then the exit-on-close semantics kick in. You can check that this is so by setting the G_DBUS_DEBUG environment variable to e.g. 'all' (or something less). The fix is, of course, in dbus-daemon-1 in this case.... let me know if you run into this problem and I'll help you file the problem at the dbus bugzilla at fd.o.
Filed relevant D-Bus bug here: https://bugs.freedesktop.org/show_bug.cgi?id=39720
Thank you. That is probably the real bug. I noticed only later that this really is only happening when the dbus server refuses authentication, and not when no dbus session is established.
Actually we shouldn't be applying the exit-on-close semantics if we fail to properly initialize the connection. I've committed a patch to fix that, see http://git.gnome.org/browse/glib/commit/?id=659ba3d0b3eca1ee3af13d277ac8c847651b0a6a Specifically, this patch makes the trivial test program in [1] do the right thing, e.g. it now prints Error connecting to session bus: The connection is closed (g-io-error-quark, 18) Running loop, exiting in two seconds <two seconds pass> Quitting loop Exiting instead of Error connecting to session bus: The connection is closed (g-io-error-quark, 18) Running loop, exiting in two seconds g_dbus_connection_real_closed: Remote peer vanished with error: Underlying GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting. Terminated So, yeah, you found a real bug in GDBus here. Thanks. [1] : #include <gio/gio.h> static gboolean on_timeout (gpointer user_data) { GMainLoop *loop = user_data; g_print ("Quitting loop\n"); g_main_loop_quit (loop); return FALSE; } int main (int argc, char *argv[]) { GDBusConnection *connection; GMainLoop *loop; GError *error; g_type_init (); error = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (connection == NULL) { g_printerr ("Error connecting to session bus: %s (%s, %d)\n", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); } else { g_print ("Connected to the session bus\n"); } loop = g_main_loop_new (NULL, FALSE); g_timeout_add (2000, on_timeout, loop); g_print ("Running loop, exiting in two seconds\n"); g_main_loop_run (loop); if (connection != NULL) g_object_unref (connection); g_main_loop_unref (loop); g_print ("Exiting\n"); return 0; }
Also cherry-picked to the glib-2-28 branch http://git.gnome.org/browse/glib/commit/?h=glib-2-28&id=012b95fe48986ebfae15d76831d909b5ce467627 in case there will ever be a 2.28.9 release.