xref: /aosp_15_r20/external/bcc/tools/deadlock_example.txt (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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