11
11
//
12
12
// ===----------------------------------------------------------------------===//
13
13
14
+ #include < sanitizer_common/sanitizer_deadlock_detector.h>
15
+
14
16
#include " tsan_rtl.h"
15
17
#include " tsan_flags.h"
16
18
#include " tsan_sync.h"
20
22
21
23
namespace __tsan {
22
24
25
+ static __sanitizer::DeadlockDetector<TwoLevelBitVector<> > g_deadlock_detector;
26
+
27
+ static void EnsureDeadlockDetectorID (ThreadState *thr, SyncVar *s) {
28
+ if (!s->deadlock_detector_id )
29
+ s->deadlock_detector_id =
30
+ g_deadlock_detector.newNode (reinterpret_cast <uptr>(s));
31
+ }
32
+
23
33
void MutexCreate (ThreadState *thr, uptr pc, uptr addr,
24
34
bool rw, bool recursive, bool linker_init) {
25
35
Context *ctx = CTX ();
@@ -35,6 +45,10 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
35
45
s->is_rw = rw;
36
46
s->is_recursive = recursive;
37
47
s->is_linker_init = linker_init;
48
+ if (common_flags ()->detect_deadlocks ) {
49
+ EnsureDeadlockDetectorID (thr, s);
50
+ Printf (" MutexCreate: %zx\n " , s->deadlock_detector_id );
51
+ }
38
52
s->mtx .Unlock ();
39
53
}
40
54
@@ -51,6 +65,10 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {
51
65
SyncVar *s = ctx->synctab .GetAndRemove (thr, pc, addr);
52
66
if (s == 0 )
53
67
return ;
68
+ if (common_flags ()->detect_deadlocks ) {
69
+ EnsureDeadlockDetectorID (thr, s);
70
+ Printf (" MutexDestroy: %zx\n " , s->deadlock_detector_id );
71
+ }
54
72
if (IsAppMem (addr)) {
55
73
CHECK (!thr->is_freeing );
56
74
thr->is_freeing = true ;
@@ -104,6 +122,15 @@ void MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec) {
104
122
}
105
123
s->recursion += rec;
106
124
thr->mset .Add (s->GetId (), true , thr->fast_state .epoch ());
125
+ if (common_flags ()->detect_deadlocks ) {
126
+ EnsureDeadlockDetectorID (thr, s);
127
+ bool has_deadlock = g_deadlock_detector.onLock (&thr->deadlock_detector_tls ,
128
+ s->deadlock_detector_id );
129
+ Printf (" MutexLock: %zx;%s\n " , s->deadlock_detector_id ,
130
+ has_deadlock
131
+ ? " ThreadSanitizer: lock-order-inversion (potential deadlock)"
132
+ : " " );
133
+ }
107
134
s->mtx .Unlock ();
108
135
}
109
136
@@ -140,6 +167,12 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all) {
140
167
}
141
168
}
142
169
thr->mset .Del (s->GetId (), true );
170
+ if (common_flags ()->detect_deadlocks ) {
171
+ EnsureDeadlockDetectorID (thr, s);
172
+ Printf (" MutexUnlock: %zx\n " , s->deadlock_detector_id );
173
+ g_deadlock_detector.onUnlock (&thr->deadlock_detector_tls ,
174
+ s->deadlock_detector_id );
175
+ }
143
176
s->mtx .Unlock ();
144
177
return rec;
145
178
}
0 commit comments