Comment 12 for bug 1820584

Revision history for this message
Elias Rudberg (eliasrudberg) wrote :

After some more digging and having reproduced the issue a few more times, here is what seems to happen.

Seahorse is running, using the avahi library. Seahorse has called avahi_glib_poll_new() and some AvahiTimeout timeouts have been created.

Then things are stopped because the computer is about to be rebooted. Seahorse is closing down and therefore does some cleanup, among other things it calls avahi_glib_poll_free() which calls cleanup_timeouts() which destroys all the timeouts.

However, after the timeouts were destroyed, there still exists a pointer to one of those timeouts in the dispatch_timeout member in a ConnectionData struct. For some reason the dispatch_timeout_callback() function is called at this point, and it does "ConnectionData *d = userdata" and that ConnectionData struct has inside it a dispatch_timeout pointer which is now invalid because the timeout was destroyed, its memory was freed, as a result of the avahi_glib_poll_free() call earlier. dispatch_timeout_callback() passes the ConnectionData *d to request_dispatch() which calls timeout_update() passing the invalid d->dispatch_timeout pointer, which is then used and happens to point to some garbage which gives the assertion failure.

Not sure exactly how to fix the problem, but it seems bad that pointers to destroyed data structures are still lying around, maybe things should be destroyed in a different order.