Created attachment 16142 [details] [review]
there is a race in send_with_reply_and_block, which can cause a timer leak.
the path is as follows:
send_with_reply creates a pending call around dbus-connection.c 3193, which registers a timer callback for timeout_miliseconds
send_with_reply_and_block calls pending_call_block which calls _dbus_connection_block_pending_call.
this function does its own timeout handling, so it can happen that the function considers that a timeout happens, even though the timeout callback was never executed. (around line 2390)
/* unlock and call user code */
complete_pending_call_and_unlock (connection, pending, NULL);
in this case, pending is destroyed without the added timer being removed, because _dbus_connection_detach_pending_call_and_unlock() removes it from the pending_replies hash table, but not calls back the user callback to remove the timer.
it can therefore happen that the timeout occurs shortly after, the reply_timeout is called, which then operates on the already unref'ed pending call and crashes.
it seems most correct to me to check for timeout_added and remove the timeout in _dbus_connection_detach_pending_call_and_unlock()
I cannot provide an easy testcase as the crash happened in a rather complex application that ran into a dbus call timeout using the Qt4 bindings.
let me know if I'm missing something.
This appears to have been applied as:
Author: Thiago Macieira <firstname.lastname@example.org>
Date: Sat May 17 10:09:20 2008 +0200
Prevent a crash in some applications due to timers leaking after the
DVusPendingCall object was freed.
* dbus-connection.c: Remove the timer for the pending call's timeout in
case the reply has timed out in blocking code. This fixes bug 15684.