If I use std::mutex and meet a deadlock, I can find which thread is holding the mutex by gdb
$ p mutex
$3 = (std::__1::mutex &) @0x7f70b56ffc90: {__m_ = {__data = {__lock = 2, __count = 0, __owner = 28539, __nusers = 1, __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, __next = 0x0}},
The __owner
field says the mutex is held by thread 28539.
However, when it comes to std::recursive_mutex
or std::shared_mutex
, things are getting harder, since I can only get the <incomplete type>
. The same error to std::shared_mutex
.
90 in /usr/local/bin/../include/c++/v1/__mutex_base
(gdb) p __m
$5 = (std::__1::lock_guard<std::__1::recursive_mutex>::mutex_type &) @0x7f163db94558: <incomplete type>
If I specify the type then
p (struct std::__recursive_mutex_base) __m
No struct type named std.
I wonder how can I know which threads holds the std::recursive_mutex
or std::shared_mutex
.
I find two ways to "fix" this:
90 /usr/local/bin/../include/c++/v1/__mutex_base: No such file or directory.
In my g++-9, there is no __mutex_base
or v1
provided. However, I find a mutex
which is quite similar to this __mutex_base
file. So I have this file modified that line 90 is exactly the definition of recursive_mutex
, then I directory /usr/include/c++
. After that p (struct std::__recursive_mutex_base) __m
will work.#include <mutex>
#include <shared_mutex>
struct r_wrapper: std::recursive_mutex {
void f() {
printf("dummy");
}
};
struct s_wrapper: std::shared_mutex {
void f() {
printf("dummy");
}
};
struct r_wrapper r_wrapper_instance;
struct s_wrapper s_wrapper_instance;
And make sure r_wrapper_instance is a symbol. Then I just add-symbol-file a.o 0
, and p (struct r_wrapper&) __m
will print.