Package: libdbus-c++-1-0v5 Version: 0.9.0-8+b1 Tags: upstream patch Severity: normal
Dear Maintainer, Sometimes I'm getting a deadlock in dbus-c++ while debugging my application under gdb. It happens when I interrupt the program when DBus request is already sent, but no reply received yet. Then I'm debugging something for 25+ sec (so dbus timeout expires), continue execution and get a deadlock in a dbus-c++ dispatcher thread. It happens for me only during gdb sessions. If I delay the reply on a DBus server side, different branch of logic is used by DBus and deadlock doesn't occur. Backtrace of the deadlock: (gdb) thread 4 [Switching to thread 4 (Thread 0xab721b40 (LWP 20192))] #0 0xb7fd9d39 in __kernel_vsyscall () (gdb) bt #0 0xb7fd9d39 in __kernel_vsyscall () #1 0xb3e0bde2 in __lll_lock_wait () from /lib/i386-linux-gnu/libpthread.so.0 #2 0xb3e0592e in pthread_mutex_lock () from /lib/i386-linux-gnu/libpthread.so.0 #3 0xb72917c8 in DBus::DefaultMutex::lock (this=0x5deb2d2c) at eventloop.cpp:104 #4 0xb7291c8a in DBus::DefaultTimeout::~DefaultTimeout (this=0x7a74a9e8, __in_chrg=<optimized out>) at eventloop.cpp:59 #5 0xb72933ce in DBus::BusTimeout::~BusTimeout (this=0x7a74a9e0, __in_chrg=<optimized out>) at ../include/dbus-c++/eventloop-integration.h:44 #6 DBus::BusTimeout::~BusTimeout (this=0x7a74a9e0, __in_chrg=<optimized out>) at ../include/dbus-c++/eventloop-integration.h:44 #7 0xb724dc43 in _dbus_timeout_list_remove_timeout (timeout_list=0x5df1b710, timeout=0x7a73e170) at ../../../dbus/dbus-timeout.c:347 #8 0xb723814a in protected_change_timeout (enabled=0, toggle_function=0x0, remove_function=<optimized out>, add_function=0x0, timeout=<optimized out>, connection=0x5df1cef8) at ../../../dbus/dbus-connection.c:841 #9 _dbus_connection_remove_timeout_unlocked (timeout=<optimized out>, connection=0x5df1cef8) at ../../../dbus/dbus-connection.c:888 #10 reply_handler_timeout (data=0x7a73ddd0) at ../../../dbus/dbus-connection.c:3344 #11 0xb7290bbb in DBus::Timeout::handle (this=0x7a74a9e0) at dispatcher.cpp:58 #12 0xb729288d in DBus::BusDispatcher::timeout_expired (this=0x5deb2ce0, et=...) at eventloop-integration.cpp:201 #13 0xb7291b52 in DBus::Slot<void, DBus::DefaultTimeout&>::operator() (param=..., this=<optimized out>) at ../include/dbus-c++/util.h:240 #14 DBus::DefaultMainLoop::dispatch (this=0x5deb2d20) at eventloop.cpp:221 #15 0xb7292610 in DBus::BusDispatcher::enter (this=0x5deb2ce0) at eventloop-integration.cpp:100 ... DBus requests are sent from another thread, but it is not participating in the deadlock. Deadlock happens in a dispatcher thread itself, which tries to lock the same non-recursive mutex it already holds: DefaultMainLoop::_mutex_t. Deadlock happens in DBus::DefaultMainLoop::dispatch() in the following code: _mutex_t.lock(); ti = _timeouts.begin(); while (ti != _timeouts.end()) { DefaultTimeouts::iterator tmp = ti; ++tmp; if ((*ti)->enabled() && now_millis >= (*ti)->_expiration) { (*ti)->expired(*(*ti)); if ((*ti)->_repeat) { (*ti)->_expiration = now_millis + (*ti)->_interval; } } ti = tmp; } _mutex_t.unlock(); It locks _mutex_t, then calls "(ti)->expired((*ti));" which just deletes the timeout, and tries to lock _mutex_t again in DefaultTimeout destructor: DefaultTimeout::~DefaultTimeout() { _disp->_mutex_t.lock(); _disp->_timeouts.remove(this); _disp->_mutex_t.unlock(); } It results in a deadlock by one thread on a non-recursive mutex. Exactly the same problem is also described here: https://sourceforge.net/p/dbus-cplusplus/mailman/message/28745127/ I've tried making DefaultMainLoop::_mutex_t recursive, and it fixed the problem. Can you please apply this patch? Patch: --- eventloop.cpp 2020-04-06 12:26:06.902743512 +0300 +++ NEW_eventloop.cpp 2020-04-06 12:26:00.838743134 +0300 @@ -110,6 +110,7 @@ } DefaultMainLoop::DefaultMainLoop() : + _mutex_t(true), _mutex_w(true) { } -- System Information: Debian Release: 9.12 APT prefers oldstable APT policy: (500, 'oldstable') Architecture: i386 (i686) Kernel: Linux 4.19.0-0.bpo.6-686-pae (SMP w/2 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968), LANGUAGE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages libdbus-c++-1-0v5 depends on: ii libc6 2.24-11+deb9u4 ii libdbus-1-3 1.10.28-0+deb9u1 ii libecore1 1.8.6-2.5+b2 ii libgcc1 1:6.3.0-18+deb9u1 ii libglib2.0-0 2.50.3-2+deb9u2 ii libstdc++6 6.3.0-18+deb9u1 libdbus-c++-1-0v5 recommends no packages. libdbus-c++-1-0v5 suggests no packages. -- no debconf information