Search code examples
c++gdb

How to identify which thread holds the std::recursive_mutex by gdb?


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.


Solution

  • I find two ways to "fix" this:

    1. I find there is an error
      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.
    2. Another way comes from Can we define a new data type in a GDB session I write the following codes
      #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.