GNOME Bugzilla – Bug 598332
Crash when CM crashes during a channel request.
Last modified: 2009-10-19 13:34:22 UTC
Created attachment 145378 [details] Debug output and backtrace. This happened to me when Empathy requested a StreamedMedia channel from the build of telepathy-haze I was working on. Telepathy-haze crashed and Empathy subsequently crashed as well. I don't believe it matters which channel type is being requested, just that the CM crashes before returning the result. I did some digging and it looks like what's happening is, in empathy-dispatcher.c, it's requesting a new channel (empathy_dispatcher_create_channel or similar) by populating a DispatcherRequestData structure and sending the request on its way. When the CM crashes and disconnects from Empathy, empathy then frees the related DispatcherRequestData in its GHashTable(s) of requests. Later, dispatcher_{create,ensure,request}_channel_cb fires, receiving an error and the now invalid/freed request_data (aka user_data in some places), and calls dispatcher_connection_new_requested_channel. In dispatcher_connection_new_requested_channel, it tries to free it again which causes some assertions. dispatcher_flush_outstanding_operations is called and Empathy finally crashes when trying to access a member of the since freed request structure (which was NULL here because this function retrieves it from a GHashTable, but it was already removed). It seems the root problem is dispatcher_{create,ensure,request}_channel_cb returning with invalid user_data. Could we store the TpProxyPendingCall(s) and tp_proxy_pending_call_cancel them when the CM disconnects?
Here's a branch of mine to fix the bug: http://git.collabora.co.uk/?p=user/maiku/empathy.git;a=shortlog;h=refs/heads/bug_598332
12:14 < smcv> Maiku: is it guaranteed that free_connection_data is called before the dispatcher (which seems to be the weak_object) is finalized? 12:14 < smcv> Maiku: if you cancel a TpProxyPendingCall after the death of the weak_object has already cancelled it, you'll crash 12:17 < smcv> Maiku: alternatively, you could give the DRD a refcount, have one ref per outstanding call (released by destroy()) plus one temporary one at the beginning, and just check for tp_proxy_get_invalidated (connection) != NULL in the callbacks
I've made some commits per your comments and our discussion: http://git.collabora.co.uk/?p=user/maiku/empathy.git;a=shortlog;h=refs/heads/bug_598332 I also found an assertion, closing the call window, once this bug was fixed and committed a patch for it: http://git.collabora.co.uk/?p=user/maiku/empathy.git;a=shortlog;h=refs/heads/close_call_window_assertion
Mike: thanks for your patches. I cherry-picked the call window fix and pushed it to both branches. I'll let Simon review the other branch as he seems to have a clear idea of the right way to fix that.
bug_598332 branch looks good to me.
I merged the 'bug_598332' to 2.28 and master. Thanks a lot to both of you. This problem has been fixed in our software repository. The fix will go into the next software release. Thank you for your bug report.