Open tasleson opened 7 years ago
I haven't been able to re-create this one, but from the stack trace we can see:
UDisksObject *
udisks_daemon_find_block (UDisksDaemon *daemon,
dev_t block_device_number)
{
UDisksObject *ret = NULL;
GList *objects, *l;
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager));
for (l = objects; l != NULL; l = l->next)
{
UDisksObject *object = UDISKS_OBJECT (l->data); // l->data is not valid as object == NULL!
UDisksBlock *block;
block = udisks_object_peek_block (object); //OBJECT IS NULL
if (block == NULL)
continue;
if (udisks_block_get_device_number (block) == block_device_number)
{
ret = g_object_ref (object);
goto out;
}
}
out:
g_list_free_full (objects, g_object_unref);
return ret;
}
Some how we have an entry being returned from the object manager where the data item has been freed. Appears to be another case of a lifetime issue or a possible race condition if we have multiple threads somehow mucking with the object manager.
Looking at GDBusObjectManagerServer
sources, their internal manager->priv->map_object_path_to_data
hashtable which the list is built from seems properly locked on any write access. The objects we get are actually nested struct members, still there are several operations performed on them and I bet you'd see a lot of critical warnings before the crash. It's also guarded with g_return_if_fail (G_IS_DBUS_OBJECT (object))
so I have no idea how this could happen. The GDBus sources look correct.
Anyway, I haven't seen this issue for over a year now. The best thing we can do here is to skip the NULL elements with serious warning printed out. This udisks_daemon_find_block()
method is about finding objects, let's pretend we didn't find one.
I'm still not convinced we want any preventive fix now as long as we haven't found the root cause. The g_dbus_object_manager_get_objects()
is used quite often at number of places (possibly chained via udisks_daemon_get_objects()
). The related object unref over the whole list would cause similar issues and making it NULL-aware would result in nasty code.
Also, typecast via UDISKS_OBJECT()
should not return NULL from a valid pointer even if the cast is invalid.
Let's keep this issue open and watch out for any occurrences.
I've seen this crash once so far. Sorry, I no longer have the core file as my /tmp was cleared on boot.