Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to determine the thread holding a mutex?

Firstly, I use pthread library to write multithreading C programs. Threads always hung by their waited mutexes. When I use the strace utility to find a thread in the FUTEX_WAIT status, I want to know which thread holds that mutex at that time. But I don't know how I could I do it. Are there any utilities that could do that?

Someone told me the Java virtual machine supports this, so I want to know whether Linux support this feature.

like image 865
terry Avatar asked Aug 14 '10 11:08

terry


People also ask

Can two threads share a mutex?

Only one thread can hold the mutex at a time, and the other thread can do no useful work.

Can two threads lock the same mutex?

The short answer is "yes".

Can a thread acquire multiple mutex?

While mutex is owned by the thread, no other thread can acquire mutex , so no other thread can be executing between either of the lock(mutex); / unlock(mutex); pairs (one at the top of the Reader function and one further down).

What is mutex and how it is related to threads?

A mutual exclusion (mutex) is used cooperatively between threads to ensure that only one of the cooperating threads is allowed to access the data or run certain application code at a time. The word mutex is shorthand for a primitive object that provides MUTual EXclusion between threads.


2 Answers

You can use knowledge of the mutex internals to do this. Ordinarily this wouldn't be a very good idea, but it's fine for debugging.

Under Linux with the NPTL implementation of pthreads (which is any modern glibc), you can examine the __data.__owner member of the pthread_mutex_t structure to find out the thread that currently has it locked. This is how to do it after attaching to the process with gdb:

(gdb) thread 2 [Switching to thread 2 (Thread 0xb6d94b90 (LWP 22026))]#0  0xb771f424 in __kernel_vsyscall () (gdb) bt #0  0xb771f424 in __kernel_vsyscall () #1  0xb76fec99 in __lll_lock_wait () from /lib/i686/cmov/libpthread.so.0 #2  0xb76fa0c4 in _L_lock_89 () from /lib/i686/cmov/libpthread.so.0 #3  0xb76f99f2 in pthread_mutex_lock () from /lib/i686/cmov/libpthread.so.0 #4  0x080484a6 in thread (x=0x0) at mutex_owner.c:8 #5  0xb76f84c0 in start_thread () from /lib/i686/cmov/libpthread.so.0 #6  0xb767784e in clone () from /lib/i686/cmov/libc.so.6 (gdb) up 4 #4  0x080484a6 in thread (x=0x0) at mutex_owner.c:8 8               pthread_mutex_lock(&mutex); (gdb) print mutex.__data.__owner $1 = 22025 (gdb) 

(I switch to the hung thread; do a backtrace to find the pthread_mutex_lock() it's stuck on; change stack frames to find out the name of the mutex that it's trying to lock; then print the owner of that mutex). This tells me that the thread with LWP ID 22025 is the culprit.

You can then use thread find 22025 to find out the gdb thread number for that thread and switch to it.

like image 50
caf Avatar answered Sep 27 '22 17:09

caf


I don't know of any such facility so I don't think you will get off that easily - and it probably wouldn't be as informative as you think in helping to debug your program. As low tech as it might seem, logging is your friend in debugging these things. Start collecting your own little logging functions. They don't have to be fancy, they just have to get the job done while debugging.

Sorry for the C++ but something like:

void logit(const bool aquired, const char* lockname, const int linenum) {     pthread_mutex_lock(&log_mutex);      if (! aquired)         logfile << pthread_self() << " tries lock " << lockname << " at " << linenum << endl;     else         logfile << pthread_self() << " has lock "   << lockname << " at " << linenum << endl;      pthread_mutex_unlock(&log_mutex); }   void someTask() {     logit(false, "some_mutex", __LINE__);      pthread_mutex_lock(&some_mutex);      logit(true, "some_mutex", __LINE__);      // do stuff ...      pthread_mutex_unlock(&some_mutex); } 

Logging isn't a perfect solution but nothing is. It usually gets you what you need to know.

like image 30
Duck Avatar answered Sep 27 '22 17:09

Duck