1*387f9dfdSAndroid Build Coastguard WorkerDemonstrations of deadlock. 2*387f9dfdSAndroid Build Coastguard Worker 3*387f9dfdSAndroid Build Coastguard WorkerThis program detects potential deadlocks on a running process. The program 4*387f9dfdSAndroid Build Coastguard Workerattaches uprobes on `pthread_mutex_lock` and `pthread_mutex_unlock` to build 5*387f9dfdSAndroid Build Coastguard Workera mutex wait directed graph, and then looks for a cycle in this graph. This 6*387f9dfdSAndroid Build Coastguard Workergraph has the following properties: 7*387f9dfdSAndroid Build Coastguard Worker 8*387f9dfdSAndroid Build Coastguard Worker- Nodes in the graph represent mutexes. 9*387f9dfdSAndroid Build Coastguard Worker- Edge (A, B) exists if there exists some thread T where lock(A) was called 10*387f9dfdSAndroid Build Coastguard Worker and lock(B) was called before unlock(A) was called. 11*387f9dfdSAndroid Build Coastguard Worker 12*387f9dfdSAndroid Build Coastguard WorkerIf there is a cycle in this graph, this indicates that there is a lock order 13*387f9dfdSAndroid Build Coastguard Workerinversion (potential deadlock). If the program finds a lock order inversion, the 14*387f9dfdSAndroid Build Coastguard Workerprogram will dump the cycle of mutexes, dump the stack traces where each mutex 15*387f9dfdSAndroid Build Coastguard Workerwas acquired, and then exit. 16*387f9dfdSAndroid Build Coastguard Worker 17*387f9dfdSAndroid Build Coastguard WorkerThis program can only find potential deadlocks that occur while the program 18*387f9dfdSAndroid Build Coastguard Workeris tracing the process. It cannot find deadlocks that may have occurred 19*387f9dfdSAndroid Build Coastguard Workerbefore the program was attached to the process. 20*387f9dfdSAndroid Build Coastguard Worker 21*387f9dfdSAndroid Build Coastguard WorkerSince this traces all mutex lock and unlock events and all thread creation 22*387f9dfdSAndroid Build Coastguard Workerevents on the traced process, the overhead of this bpf program can be very 23*387f9dfdSAndroid Build Coastguard Workerhigh if the process has many threads and mutexes. You should only run this on 24*387f9dfdSAndroid Build Coastguard Workera process where the slowdown is acceptable. 25*387f9dfdSAndroid Build Coastguard Worker 26*387f9dfdSAndroid Build Coastguard WorkerNote: This tool does not work for shared mutexes or recursive mutexes. 27*387f9dfdSAndroid Build Coastguard Worker 28*387f9dfdSAndroid Build Coastguard WorkerFor shared (read-write) mutexes, a deadlock requires a cycle in the wait 29*387f9dfdSAndroid Build Coastguard Workergraph where at least one of the mutexes in the cycle is acquiring exclusive 30*387f9dfdSAndroid Build Coastguard Worker(write) ownership. 31*387f9dfdSAndroid Build Coastguard Worker 32*387f9dfdSAndroid Build Coastguard WorkerFor recursive mutexes, lock() is called multiple times on the same mutex. 33*387f9dfdSAndroid Build Coastguard WorkerHowever, there is no way to determine if a mutex is a recursive mutex 34*387f9dfdSAndroid Build Coastguard Workerafter the mutex has been created. As a result, this tool will not find 35*387f9dfdSAndroid Build Coastguard Workerpotential deadlocks that involve only one mutex. 36*387f9dfdSAndroid Build Coastguard Worker 37*387f9dfdSAndroid Build Coastguard Worker 38*387f9dfdSAndroid Build Coastguard Worker# ./deadlock.py 181 39*387f9dfdSAndroid Build Coastguard WorkerTracing... Hit Ctrl-C to end. 40*387f9dfdSAndroid Build Coastguard Worker---------------- 41*387f9dfdSAndroid Build Coastguard WorkerPotential Deadlock Detected! 42*387f9dfdSAndroid Build Coastguard Worker 43*387f9dfdSAndroid Build Coastguard WorkerCycle in lock order graph: Mutex M0 (main::static_mutex3 0x0000000000473c60) => Mutex M1 (0x00007fff6d738400) => Mutex M2 (global_mutex1 0x0000000000473be0) => Mutex M3 (global_mutex2 0x0000000000473c20) => Mutex M0 (main::static_mutex3 0x0000000000473c60) 44*387f9dfdSAndroid Build Coastguard Worker 45*387f9dfdSAndroid Build Coastguard WorkerMutex M1 (0x00007fff6d738400) acquired here while holding Mutex M0 (main::static_mutex3 0x0000000000473c60) in Thread 357250 (lockinversion): 46*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 47*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 48*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 49*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402e38 main::{lambda()#3}::operator()() const 50*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406ba8 void std::_Bind_simple<main::{lambda()#3} ()>::_M_invoke<>(std::_Index_tuple<>) 51*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406951 std::_Bind_simple<main::{lambda()#3} ()>::operator()() 52*387f9dfdSAndroid Build Coastguard Worker@ 000000000040673a std::thread::_Impl<std::_Bind_simple<main::{lambda()#3} ()> >::_M_run() 53*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 54*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 55*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 56*387f9dfdSAndroid Build Coastguard Worker 57*387f9dfdSAndroid Build Coastguard WorkerMutex M0 (main::static_mutex3 0x0000000000473c60) previously acquired by the same Thread 357250 (lockinversion) here: 58*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 59*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 60*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 61*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402e22 main::{lambda()#3}::operator()() const 62*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406ba8 void std::_Bind_simple<main::{lambda()#3} ()>::_M_invoke<>(std::_Index_tuple<>) 63*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406951 std::_Bind_simple<main::{lambda()#3} ()>::operator()() 64*387f9dfdSAndroid Build Coastguard Worker@ 000000000040673a std::thread::_Impl<std::_Bind_simple<main::{lambda()#3} ()> >::_M_run() 65*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 66*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 67*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 68*387f9dfdSAndroid Build Coastguard Worker 69*387f9dfdSAndroid Build Coastguard WorkerMutex M2 (global_mutex1 0x0000000000473be0) acquired here while holding Mutex M1 (0x00007fff6d738400) in Thread 357251 (lockinversion): 70*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 71*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 72*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 73*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402ea8 main::{lambda()#4}::operator()() const 74*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406b46 void std::_Bind_simple<main::{lambda()#4} ()>::_M_invoke<>(std::_Index_tuple<>) 75*387f9dfdSAndroid Build Coastguard Worker@ 000000000040692d std::_Bind_simple<main::{lambda()#4} ()>::operator()() 76*387f9dfdSAndroid Build Coastguard Worker@ 000000000040671c std::thread::_Impl<std::_Bind_simple<main::{lambda()#4} ()> >::_M_run() 77*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 78*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 79*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 80*387f9dfdSAndroid Build Coastguard Worker 81*387f9dfdSAndroid Build Coastguard WorkerMutex M1 (0x00007fff6d738400) previously acquired by the same Thread 357251 (lockinversion) here: 82*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 83*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 84*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 85*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402e97 main::{lambda()#4}::operator()() const 86*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406b46 void std::_Bind_simple<main::{lambda()#4} ()>::_M_invoke<>(std::_Index_tuple<>) 87*387f9dfdSAndroid Build Coastguard Worker@ 000000000040692d std::_Bind_simple<main::{lambda()#4} ()>::operator()() 88*387f9dfdSAndroid Build Coastguard Worker@ 000000000040671c std::thread::_Impl<std::_Bind_simple<main::{lambda()#4} ()> >::_M_run() 89*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 90*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 91*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 92*387f9dfdSAndroid Build Coastguard Worker 93*387f9dfdSAndroid Build Coastguard WorkerMutex M3 (global_mutex2 0x0000000000473c20) acquired here while holding Mutex M2 (global_mutex1 0x0000000000473be0) in Thread 357247 (lockinversion): 94*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 95*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 96*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 97*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402d5f main::{lambda()#1}::operator()() const 98*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406c6c void std::_Bind_simple<main::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) 99*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406999 std::_Bind_simple<main::{lambda()#1} ()>::operator()() 100*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406776 std::thread::_Impl<std::_Bind_simple<main::{lambda()#1} ()> >::_M_run() 101*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 102*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 103*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 104*387f9dfdSAndroid Build Coastguard Worker 105*387f9dfdSAndroid Build Coastguard WorkerMutex M2 (global_mutex1 0x0000000000473be0) previously acquired by the same Thread 357247 (lockinversion) here: 106*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 107*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 108*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 109*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402d4e main::{lambda()#1}::operator()() const 110*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406c6c void std::_Bind_simple<main::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) 111*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406999 std::_Bind_simple<main::{lambda()#1} ()>::operator()() 112*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406776 std::thread::_Impl<std::_Bind_simple<main::{lambda()#1} ()> >::_M_run() 113*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 114*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 115*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 116*387f9dfdSAndroid Build Coastguard Worker 117*387f9dfdSAndroid Build Coastguard WorkerMutex M0 (main::static_mutex3 0x0000000000473c60) acquired here while holding Mutex M3 (global_mutex2 0x0000000000473c20) in Thread 357248 (lockinversion): 118*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 119*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 120*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 121*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402dc9 main::{lambda()#2}::operator()() const 122*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406c0a void std::_Bind_simple<main::{lambda()#2} ()>::_M_invoke<>(std::_Index_tuple<>) 123*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406975 std::_Bind_simple<main::{lambda()#2} ()>::operator()() 124*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406758 std::thread::_Impl<std::_Bind_simple<main::{lambda()#2} ()> >::_M_run() 125*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 126*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 127*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 128*387f9dfdSAndroid Build Coastguard Worker 129*387f9dfdSAndroid Build Coastguard WorkerMutex M3 (global_mutex2 0x0000000000473c20) previously acquired by the same Thread 357248 (lockinversion) here: 130*387f9dfdSAndroid Build Coastguard Worker@ 00000000004024d0 pthread_mutex_lock 131*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406dd0 std::mutex::lock() 132*387f9dfdSAndroid Build Coastguard Worker@ 00000000004070d2 std::lock_guard<std::mutex>::lock_guard(std::mutex&) 133*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402db8 main::{lambda()#2}::operator()() const 134*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406c0a void std::_Bind_simple<main::{lambda()#2} ()>::_M_invoke<>(std::_Index_tuple<>) 135*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406975 std::_Bind_simple<main::{lambda()#2} ()>::operator()() 136*387f9dfdSAndroid Build Coastguard Worker@ 0000000000406758 std::thread::_Impl<std::_Bind_simple<main::{lambda()#2} ()> >::_M_run() 137*387f9dfdSAndroid Build Coastguard Worker@ 00007fd4496564e1 execute_native_thread_routine 138*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd57f1 start_thread 139*387f9dfdSAndroid Build Coastguard Worker@ 00007fd44909746d __clone 140*387f9dfdSAndroid Build Coastguard Worker 141*387f9dfdSAndroid Build Coastguard WorkerThread 357248 created by Thread 350692 (lockinversion) here: 142*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449097431 __clone 143*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd5ef5 pthread_create 144*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449658440 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) 145*387f9dfdSAndroid Build Coastguard Worker@ 00000000004033ac std::thread::thread<main::{lambda()#2}>(main::{lambda()#2}&&) 146*387f9dfdSAndroid Build Coastguard Worker@ 000000000040308f main 147*387f9dfdSAndroid Build Coastguard Worker@ 00007fd448faa0f6 __libc_start_main 148*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402ad8 [unknown] 149*387f9dfdSAndroid Build Coastguard Worker 150*387f9dfdSAndroid Build Coastguard WorkerThread 357250 created by Thread 350692 (lockinversion) here: 151*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449097431 __clone 152*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd5ef5 pthread_create 153*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449658440 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) 154*387f9dfdSAndroid Build Coastguard Worker@ 00000000004034b2 std::thread::thread<main::{lambda()#3}>(main::{lambda()#3}&&) 155*387f9dfdSAndroid Build Coastguard Worker@ 00000000004030b9 main 156*387f9dfdSAndroid Build Coastguard Worker@ 00007fd448faa0f6 __libc_start_main 157*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402ad8 [unknown] 158*387f9dfdSAndroid Build Coastguard Worker 159*387f9dfdSAndroid Build Coastguard WorkerThread 357251 created by Thread 350692 (lockinversion) here: 160*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449097431 __clone 161*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd5ef5 pthread_create 162*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449658440 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) 163*387f9dfdSAndroid Build Coastguard Worker@ 00000000004035b8 std::thread::thread<main::{lambda()#4}>(main::{lambda()#4}&&) 164*387f9dfdSAndroid Build Coastguard Worker@ 00000000004030e6 main 165*387f9dfdSAndroid Build Coastguard Worker@ 00007fd448faa0f6 __libc_start_main 166*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402ad8 [unknown] 167*387f9dfdSAndroid Build Coastguard Worker 168*387f9dfdSAndroid Build Coastguard WorkerThread 357247 created by Thread 350692 (lockinversion) here: 169*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449097431 __clone 170*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449dd5ef5 pthread_create 171*387f9dfdSAndroid Build Coastguard Worker@ 00007fd449658440 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) 172*387f9dfdSAndroid Build Coastguard Worker@ 00000000004032a6 std::thread::thread<main::{lambda()#1}>(main::{lambda()#1}&&) 173*387f9dfdSAndroid Build Coastguard Worker@ 0000000000403070 main 174*387f9dfdSAndroid Build Coastguard Worker@ 00007fd448faa0f6 __libc_start_main 175*387f9dfdSAndroid Build Coastguard Worker@ 0000000000402ad8 [unknown] 176*387f9dfdSAndroid Build Coastguard Worker 177*387f9dfdSAndroid Build Coastguard WorkerThis is output from a process that has a potential deadlock involving 4 mutexes 178*387f9dfdSAndroid Build Coastguard Workerand 4 threads: 179*387f9dfdSAndroid Build Coastguard Worker 180*387f9dfdSAndroid Build Coastguard Worker- Thread 357250 acquired M1 while holding M0 (edge M0 -> M1) 181*387f9dfdSAndroid Build Coastguard Worker- Thread 357251 acquired M2 while holding M1 (edge M1 -> M2) 182*387f9dfdSAndroid Build Coastguard Worker- Thread 357247 acquired M3 while holding M2 (edge M2 -> M3) 183*387f9dfdSAndroid Build Coastguard Worker- Thread 357248 acquired M0 while holding M3 (edge M3 -> M0) 184*387f9dfdSAndroid Build Coastguard Worker 185*387f9dfdSAndroid Build Coastguard WorkerThis is the C++ program that generated the output above: 186*387f9dfdSAndroid Build Coastguard Worker 187*387f9dfdSAndroid Build Coastguard Worker```c++ 188*387f9dfdSAndroid Build Coastguard Worker#include <chrono> 189*387f9dfdSAndroid Build Coastguard Worker#include <iostream> 190*387f9dfdSAndroid Build Coastguard Worker#include <mutex> 191*387f9dfdSAndroid Build Coastguard Worker#include <thread> 192*387f9dfdSAndroid Build Coastguard Worker 193*387f9dfdSAndroid Build Coastguard Workerstd::mutex global_mutex1; 194*387f9dfdSAndroid Build Coastguard Workerstd::mutex global_mutex2; 195*387f9dfdSAndroid Build Coastguard Worker 196*387f9dfdSAndroid Build Coastguard Workerint main(void) { 197*387f9dfdSAndroid Build Coastguard Worker static std::mutex static_mutex3; 198*387f9dfdSAndroid Build Coastguard Worker std::mutex local_mutex4; 199*387f9dfdSAndroid Build Coastguard Worker 200*387f9dfdSAndroid Build Coastguard Worker std::cout << "sleeping for a bit to allow trace to attach..." << std::endl; 201*387f9dfdSAndroid Build Coastguard Worker std::this_thread::sleep_for(std::chrono::seconds(10)); 202*387f9dfdSAndroid Build Coastguard Worker std::cout << "starting program..." << std::endl; 203*387f9dfdSAndroid Build Coastguard Worker 204*387f9dfdSAndroid Build Coastguard Worker auto t1 = std::thread([] { 205*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g1(global_mutex1); 206*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g2(global_mutex2); 207*387f9dfdSAndroid Build Coastguard Worker }); 208*387f9dfdSAndroid Build Coastguard Worker t1.join(); 209*387f9dfdSAndroid Build Coastguard Worker 210*387f9dfdSAndroid Build Coastguard Worker auto t2 = std::thread([] { 211*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g2(global_mutex2); 212*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g3(static_mutex3); 213*387f9dfdSAndroid Build Coastguard Worker }); 214*387f9dfdSAndroid Build Coastguard Worker t2.join(); 215*387f9dfdSAndroid Build Coastguard Worker 216*387f9dfdSAndroid Build Coastguard Worker auto t3 = std::thread([&local_mutex4] { 217*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g3(static_mutex3); 218*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g4(local_mutex4); 219*387f9dfdSAndroid Build Coastguard Worker }); 220*387f9dfdSAndroid Build Coastguard Worker t3.join(); 221*387f9dfdSAndroid Build Coastguard Worker 222*387f9dfdSAndroid Build Coastguard Worker auto t4 = std::thread([&local_mutex4] { 223*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g4(local_mutex4); 224*387f9dfdSAndroid Build Coastguard Worker std::lock_guard<std::mutex> g1(global_mutex1); 225*387f9dfdSAndroid Build Coastguard Worker }); 226*387f9dfdSAndroid Build Coastguard Worker t4.join(); 227*387f9dfdSAndroid Build Coastguard Worker 228*387f9dfdSAndroid Build Coastguard Worker std::cout << "sleeping to allow trace to collect data..." << std::endl; 229*387f9dfdSAndroid Build Coastguard Worker std::this_thread::sleep_for(std::chrono::seconds(5)); 230*387f9dfdSAndroid Build Coastguard Worker std::cout << "done!" << std::endl; 231*387f9dfdSAndroid Build Coastguard Worker} 232*387f9dfdSAndroid Build Coastguard Worker``` 233*387f9dfdSAndroid Build Coastguard Worker 234*387f9dfdSAndroid Build Coastguard WorkerNote that an actual deadlock did not occur, although this mutex lock ordering 235*387f9dfdSAndroid Build Coastguard Workercreates the possibility of a deadlock, and this is a hint to the programmer to 236*387f9dfdSAndroid Build Coastguard Workerreconsider the lock ordering. If the mutexes are global or static and debug 237*387f9dfdSAndroid Build Coastguard Workersymbols are enabled, the output will contain the mutex symbol name. The output 238*387f9dfdSAndroid Build Coastguard Workeruses a similar format as ThreadSanitizer 239*387f9dfdSAndroid Build Coastguard Worker(https://github.com/google/sanitizers/wiki/ThreadSanitizerDeadlockDetector). 240*387f9dfdSAndroid Build Coastguard Worker 241*387f9dfdSAndroid Build Coastguard Worker 242*387f9dfdSAndroid Build Coastguard Worker# ./deadlock.py 181 --binary /usr/local/bin/lockinversion 243*387f9dfdSAndroid Build Coastguard Worker 244*387f9dfdSAndroid Build Coastguard WorkerTracing... Hit Ctrl-C to end. 245*387f9dfdSAndroid Build Coastguard Worker^C 246*387f9dfdSAndroid Build Coastguard Worker 247*387f9dfdSAndroid Build Coastguard WorkerIf the traced process is instantiated from a statically-linked executable, 248*387f9dfdSAndroid Build Coastguard Workerthis argument is optional, and the program will determine the path of the 249*387f9dfdSAndroid Build Coastguard Workerexecutable from the pid. However, on older kernels without this patch 250*387f9dfdSAndroid Build Coastguard Worker("uprobe: Find last occurrence of ':' when parsing uprobe PATH:OFFSET", 251*387f9dfdSAndroid Build Coastguard Workerhttps://lkml.org/lkml/2017/1/13/585), binaries that contain `:` in the path 252*387f9dfdSAndroid Build Coastguard Workercannot be attached with uprobes. As a workaround, we can create a symlink 253*387f9dfdSAndroid Build Coastguard Workerto the binary, and provide the symlink name instead to the `--binary` option. 254*387f9dfdSAndroid Build Coastguard Worker 255*387f9dfdSAndroid Build Coastguard Worker 256*387f9dfdSAndroid Build Coastguard Worker# ./deadlock.py 181 --binary /lib/x86_64-linux-gnu/libpthread.so.0 257*387f9dfdSAndroid Build Coastguard Worker 258*387f9dfdSAndroid Build Coastguard WorkerTracing... Hit Ctrl-C to end. 259*387f9dfdSAndroid Build Coastguard Worker^C 260*387f9dfdSAndroid Build Coastguard Worker 261*387f9dfdSAndroid Build Coastguard WorkerIf the traced process is instantiated from a dynamically-linked executable, 262*387f9dfdSAndroid Build Coastguard Workerthis argument is required and needs to be the path to the pthread shared 263*387f9dfdSAndroid Build Coastguard Workerlibrary used by the executable. 264*387f9dfdSAndroid Build Coastguard Worker 265*387f9dfdSAndroid Build Coastguard Worker 266*387f9dfdSAndroid Build Coastguard Worker# ./deadlock.py 181 --dump-graph graph.json --verbose 267*387f9dfdSAndroid Build Coastguard Worker 268*387f9dfdSAndroid Build Coastguard WorkerTracing... Hit Ctrl-C to end. 269*387f9dfdSAndroid Build Coastguard WorkerMutexes: 0, Edges: 0 270*387f9dfdSAndroid Build Coastguard WorkerMutexes: 532, Edges: 411 271*387f9dfdSAndroid Build Coastguard WorkerMutexes: 735, Edges: 675 272*387f9dfdSAndroid Build Coastguard WorkerMutexes: 1118, Edges: 1278 273*387f9dfdSAndroid Build Coastguard WorkerMutexes: 1666, Edges: 2185 274*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2056, Edges: 2694 275*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2245, Edges: 2906 276*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2656, Edges: 3479 277*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2813, Edges: 3785 278*387f9dfdSAndroid Build Coastguard Worker^C 279*387f9dfdSAndroid Build Coastguard Worker 280*387f9dfdSAndroid Build Coastguard WorkerIf the program does not find a deadlock, it will keep running until you hit 281*387f9dfdSAndroid Build Coastguard WorkerCtrl-C. If you pass the `--verbose` flag, the program will also dump statistics 282*387f9dfdSAndroid Build Coastguard Workerabout the number of mutexes and edges in the mutex wait graph. If you want to 283*387f9dfdSAndroid Build Coastguard Workerserialize the graph to analyze it later, you can pass the `--dump-graph FILE` 284*387f9dfdSAndroid Build Coastguard Workerflag, and the program will serialize the graph in json. 285*387f9dfdSAndroid Build Coastguard Worker 286*387f9dfdSAndroid Build Coastguard Worker 287*387f9dfdSAndroid Build Coastguard Worker# ./deadlock.py 181 --lock-symbols custom_mutex1_lock,custom_mutex2_lock --unlock_symbols custom_mutex1_unlock,custom_mutex2_unlock --verbose 288*387f9dfdSAndroid Build Coastguard Worker 289*387f9dfdSAndroid Build Coastguard WorkerTracing... Hit Ctrl-C to end. 290*387f9dfdSAndroid Build Coastguard WorkerMutexes: 0, Edges: 0 291*387f9dfdSAndroid Build Coastguard WorkerMutexes: 532, Edges: 411 292*387f9dfdSAndroid Build Coastguard WorkerMutexes: 735, Edges: 675 293*387f9dfdSAndroid Build Coastguard WorkerMutexes: 1118, Edges: 1278 294*387f9dfdSAndroid Build Coastguard WorkerMutexes: 1666, Edges: 2185 295*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2056, Edges: 2694 296*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2245, Edges: 2906 297*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2656, Edges: 3479 298*387f9dfdSAndroid Build Coastguard WorkerMutexes: 2813, Edges: 3785 299*387f9dfdSAndroid Build Coastguard Worker^C 300*387f9dfdSAndroid Build Coastguard Worker 301*387f9dfdSAndroid Build Coastguard WorkerIf your program is using custom mutexes and not pthread mutexes, you can use 302*387f9dfdSAndroid Build Coastguard Workerthe `--lock-symbols` and `--unlock-symbols` flags to specify different mutex 303*387f9dfdSAndroid Build Coastguard Workersymbols to trace. The flags take a comma-separated string of symbol names. 304*387f9dfdSAndroid Build Coastguard WorkerNote that if the symbols are inlined in the binary, then this program can result 305*387f9dfdSAndroid Build Coastguard Workerin false positives. 306*387f9dfdSAndroid Build Coastguard Worker 307*387f9dfdSAndroid Build Coastguard Worker 308*387f9dfdSAndroid Build Coastguard WorkerUSAGE message: 309*387f9dfdSAndroid Build Coastguard Worker 310*387f9dfdSAndroid Build Coastguard Worker# ./deadlock.py -h 311*387f9dfdSAndroid Build Coastguard Worker 312*387f9dfdSAndroid Build Coastguard Workerusage: deadlock.py [-h] [--binary BINARY] [--dump-graph DUMP_GRAPH] 313*387f9dfdSAndroid Build Coastguard Worker [--verbose] [--lock-symbols LOCK_SYMBOLS] 314*387f9dfdSAndroid Build Coastguard Worker [--unlock-symbols UNLOCK_SYMBOLS] 315*387f9dfdSAndroid Build Coastguard Worker pid 316*387f9dfdSAndroid Build Coastguard Worker 317*387f9dfdSAndroid Build Coastguard WorkerDetect potential deadlocks (lock inversions) in a running binary. 318*387f9dfdSAndroid Build Coastguard WorkerMust be run as root. 319*387f9dfdSAndroid Build Coastguard Worker 320*387f9dfdSAndroid Build Coastguard Workerpositional arguments: 321*387f9dfdSAndroid Build Coastguard Worker pid Pid to trace 322*387f9dfdSAndroid Build Coastguard Worker 323*387f9dfdSAndroid Build Coastguard Workeroptional arguments: 324*387f9dfdSAndroid Build Coastguard Worker -h, --help show this help message and exit 325*387f9dfdSAndroid Build Coastguard Worker --binary BINARY If set, trace the mutexes from the binary at this 326*387f9dfdSAndroid Build Coastguard Worker path. For statically-linked binaries, this argument is 327*387f9dfdSAndroid Build Coastguard Worker not required. For dynamically-linked binaries, this 328*387f9dfdSAndroid Build Coastguard Worker argument is required and should be the path of the 329*387f9dfdSAndroid Build Coastguard Worker pthread library the binary is using. Example: 330*387f9dfdSAndroid Build Coastguard Worker /lib/x86_64-linux-gnu/libpthread.so.0 331*387f9dfdSAndroid Build Coastguard Worker --dump-graph DUMP_GRAPH 332*387f9dfdSAndroid Build Coastguard Worker If set, this will dump the mutex graph to the 333*387f9dfdSAndroid Build Coastguard Worker specified file. 334*387f9dfdSAndroid Build Coastguard Worker --verbose Print statistics about the mutex wait graph. 335*387f9dfdSAndroid Build Coastguard Worker --lock-symbols LOCK_SYMBOLS 336*387f9dfdSAndroid Build Coastguard Worker Comma-separated list of lock symbols to trace. Default 337*387f9dfdSAndroid Build Coastguard Worker is pthread_mutex_lock. These symbols cannot be inlined 338*387f9dfdSAndroid Build Coastguard Worker in the binary. 339*387f9dfdSAndroid Build Coastguard Worker --unlock-symbols UNLOCK_SYMBOLS 340*387f9dfdSAndroid Build Coastguard Worker Comma-separated list of unlock symbols to trace. 341*387f9dfdSAndroid Build Coastguard Worker Default is pthread_mutex_unlock. These symbols cannot 342*387f9dfdSAndroid Build Coastguard Worker be inlined in the binary. 343*387f9dfdSAndroid Build Coastguard Worker -t THREADS, --threads THREADS 344*387f9dfdSAndroid Build Coastguard Worker Specifies the maximum number of threads to trace. 345*387f9dfdSAndroid Build Coastguard Worker default 65536. Note. 40 bytes per thread. 346*387f9dfdSAndroid Build Coastguard Worker -e EDGES, --edges EDGES 347*387f9dfdSAndroid Build Coastguard Worker Specifies the maximum number of edge cases that can be 348*387f9dfdSAndroid Build Coastguard Worker recorded. default 65536. Note. 88 bytes per edge case. 349*387f9dfdSAndroid Build Coastguard Worker 350*387f9dfdSAndroid Build Coastguard WorkerExamples: 351*387f9dfdSAndroid Build Coastguard Worker deadlock 181 # Analyze PID 181 352*387f9dfdSAndroid Build Coastguard Worker 353*387f9dfdSAndroid Build Coastguard Worker deadlock 181 --binary /lib/x86_64-linux-gnu/libpthread.so.0 354*387f9dfdSAndroid Build Coastguard Worker # Analyze PID 181 and locks from this binary. 355*387f9dfdSAndroid Build Coastguard Worker # If tracing a process that is running from 356*387f9dfdSAndroid Build Coastguard Worker # a dynamically-linked binary, this argument 357*387f9dfdSAndroid Build Coastguard Worker # is required and should be the path to the 358*387f9dfdSAndroid Build Coastguard Worker # pthread library. 359*387f9dfdSAndroid Build Coastguard Worker 360*387f9dfdSAndroid Build Coastguard Worker deadlock 181 --verbose 361*387f9dfdSAndroid Build Coastguard Worker # Analyze PID 181 and print statistics about 362*387f9dfdSAndroid Build Coastguard Worker # the mutex wait graph. 363*387f9dfdSAndroid Build Coastguard Worker 364*387f9dfdSAndroid Build Coastguard Worker deadlock 181 --lock-symbols my_mutex_lock1,my_mutex_lock2 \ 365*387f9dfdSAndroid Build Coastguard Worker --unlock-symbols my_mutex_unlock1,my_mutex_unlock2 366*387f9dfdSAndroid Build Coastguard Worker # Analyze PID 181 and trace custom mutex 367*387f9dfdSAndroid Build Coastguard Worker # symbols instead of pthread mutexes. 368*387f9dfdSAndroid Build Coastguard Worker 369*387f9dfdSAndroid Build Coastguard Worker deadlock 181 --dump-graph graph.json 370*387f9dfdSAndroid Build Coastguard Worker # Analyze PID 181 and dump the mutex wait 371*387f9dfdSAndroid Build Coastguard Worker # graph to graph.json. 372