is what triggered me to look at this. It has the following stacktrace
#0 io_handler_watch_freed (data=0x0) at dbus-gmain.c:198
No locals.
#1 0x00007fde8af8565b in dbus_watch_set_data (watch=0x24b8090, data=0x0,
free_data_function=0) at dbus-watch.c:602
No locals.
#2 0x00007fde8af85881 in _dbus_watch_unref (watch=0x0) at dbus-watch.c:131
No locals.
#3 0x00007fde8af84e89 in free_watches (transport=0x2305d70)
at dbus-transport-socket.c:83
No locals.
#4 0x00007fde8af84ee9 in socket_disconnect (transport=0x0)
at dbus-transport-socket.c:928
No locals.
#5 0x00007fde8af82ea7 in _dbus_transport_disconnect (transport=0x2305d70)
at dbus-transport.c:494
No locals.
#6 0x00007fde8af838a3 in _dbus_transport_queue_messages (transport=0x2305d70)
at dbus-transport.c:1137
status = <value optimized out>
It looks to me as though dbus-glib isn't taking part in dbus' reference counting:
Hi,
https:/ /bugs.launchpad .net/ubuntu/ +source/ dbus-glib/ +bug/441190
is what triggered me to look at this. It has the following stacktrace
#0 io_handler_ watch_freed (data=0x0) at dbus-gmain.c:198 data_function= 0) at dbus-watch.c:602 0x2305d70) socket. c:83 socket. c:928 _disconnect (transport= 0x2305d70) c:494 _queue_ messages (transport= 0x2305d70) c:1137
No locals.
#1 0x00007fde8af8565b in dbus_watch_set_data (watch=0x24b8090, data=0x0,
free_
No locals.
#2 0x00007fde8af85881 in _dbus_watch_unref (watch=0x0) at dbus-watch.c:131
No locals.
#3 0x00007fde8af84e89 in free_watches (transport=
at dbus-transport-
No locals.
#4 0x00007fde8af84ee9 in socket_disconnect (transport=0x0)
at dbus-transport-
No locals.
#5 0x00007fde8af82ea7 in _dbus_transport
at dbus-transport.
No locals.
#6 0x00007fde8af838a3 in _dbus_transport
at dbus-transport.
status = <value optimized out>
It looks to me as though dbus-glib isn't taking part in dbus' reference counting:
In dbus, as things are being torn down:
_dbus_ watch_unref( ...
dbus_watch_ set_data (watch, NULL, NULL); /* call free_data_function */
.
.
.
if (watch->refcount == 0)
{
which frees the data.
in dbus-glib
connection_ setup_add_ watch(. .. unix_new (dbus_watch_ get_unix_ fd (watch));
.
.
.
channel = g_io_channel_
handler->source = g_io_create_watch (channel, condition); set_callback (handler->source, (GSourceFunc) io_handler_ dispatch, handler,
io_ handler_ source_ finalized) ;
g_source_
so io_handler_ source_ finalized will be called as the watch is torn down
io_handler_ source_ finalized (gpointer data)
{
IOHandler *handler;
handler = data;
if (handler->watch) watch_set_ data (handler->watch, NULL, NULL);
dbus_
which frees the data regardless.
This isn't a race, the way io_handler_ watch_freed is coded, it will
crash regardless of the ordering here.
I think this isn't an issue for every use, as we are in an exception case in
dbus itself:
if (_dbus_ message_ loader_ get_is_ corrupted (transport- >loader) ) dbus_transport_ disconnect (transport);
{
_dbus_verbose ("Corrupted message stream, disconnecting\n");
_
As for a fix, I'm not sure, should dbus-glib take part in the refcounting,
or just not bother freeing the data and rely on dbus to do it?
Thanks,
James