1 //===-- tsan_interface_ann.cc ---------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
12 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common/sanitizer_libc.h"
14 #include "sanitizer_common/sanitizer_internal_defs.h"
15 #include "sanitizer_common/sanitizer_placement_new.h"
16 #include "sanitizer_common/sanitizer_stacktrace.h"
17 #include "tsan_interface_ann.h"
18 #include "tsan_mutex.h"
19 #include "tsan_report.h"
21 #include "tsan_mman.h"
22 #include "tsan_flags.h"
23 #include "tsan_platform.h"
24 #include "tsan_vector.h"
26 #define CALLERPC ((uptr)__builtin_return_address(0))
28 using namespace __tsan
; // NOLINT
32 class ScopedAnnotation
{
34 ScopedAnnotation(ThreadState
*thr
, const char *aname
, const char *f
, int l
,
37 , in_rtl_(thr
->in_rtl
) {
38 CHECK_EQ(thr_
->in_rtl
, 0);
41 DPrintf("#%d: annotation %s() %s:%d\n", thr_
->tid
, aname
, f
, l
);
46 CHECK_EQ(in_rtl_
, thr_
->in_rtl
);
50 ThreadState
*const thr_
;
54 #define SCOPED_ANNOTATION(typ) \
55 if (!flags()->enable_annotations) \
57 ThreadState *thr = cur_thread(); \
58 const uptr caller_pc = (uptr)__builtin_return_address(0); \
59 StatInc(thr, StatAnnotation); \
60 StatInc(thr, Stat##typ); \
61 ScopedAnnotation sa(thr, __FUNCTION__, f, l, caller_pc); \
62 const uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
66 static const int kMaxDescLen
= 128;
77 char desc
[kMaxDescLen
];
80 struct DynamicAnnContext
{
86 : mtx(MutexTypeAnnotations
, StatMtxAnnotations
) {
90 static DynamicAnnContext
*dyn_ann_ctx
;
91 static char dyn_ann_ctx_placeholder
[sizeof(DynamicAnnContext
)] ALIGNED(64);
93 static void AddExpectRace(ExpectRace
*list
,
94 char *f
, int l
, uptr addr
, uptr size
, char *desc
) {
95 ExpectRace
*race
= list
->next
;
96 for (; race
!= list
; race
= race
->next
) {
97 if (race
->addr
== addr
&& race
->size
== size
) {
102 race
= (ExpectRace
*)internal_alloc(MBlockExpectRace
, sizeof(ExpectRace
));
112 for (; i
< kMaxDescLen
- 1 && desc
[i
]; i
++)
113 race
->desc
[i
] = desc
[i
];
117 race
->next
= list
->next
;
118 race
->next
->prev
= race
;
122 static ExpectRace
*FindRace(ExpectRace
*list
, uptr addr
, uptr size
) {
123 for (ExpectRace
*race
= list
->next
; race
!= list
; race
= race
->next
) {
124 uptr maxbegin
= max(race
->addr
, addr
);
125 uptr minend
= min(race
->addr
+ race
->size
, addr
+ size
);
126 if (maxbegin
< minend
)
132 static bool CheckContains(ExpectRace
*list
, uptr addr
, uptr size
) {
133 ExpectRace
*race
= FindRace(list
, addr
, size
);
134 if (race
== 0 && AlternativeAddress(addr
))
135 race
= FindRace(list
, AlternativeAddress(addr
), size
);
138 DPrintf("Hit expected/benign race: %s addr=%zx:%d %s:%d\n",
139 race
->desc
, race
->addr
, (int)race
->size
, race
->file
, race
->line
);
144 static void InitList(ExpectRace
*list
) {
149 void InitializeDynamicAnnotations() {
150 dyn_ann_ctx
= new(dyn_ann_ctx_placeholder
) DynamicAnnContext
;
151 InitList(&dyn_ann_ctx
->expect
);
152 InitList(&dyn_ann_ctx
->benign
);
155 bool IsExpectedReport(uptr addr
, uptr size
) {
156 Lock
lock(&dyn_ann_ctx
->mtx
);
157 if (CheckContains(&dyn_ann_ctx
->expect
, addr
, size
))
159 if (CheckContains(&dyn_ann_ctx
->benign
, addr
, size
))
164 static void CollectMatchedBenignRaces(Vector
<ExpectRace
> *matched
,
165 int *unique_count
, int *hit_count
, int ExpectRace::*counter
) {
166 ExpectRace
*list
= &dyn_ann_ctx
->benign
;
167 for (ExpectRace
*race
= list
->next
; race
!= list
; race
= race
->next
) {
169 if (race
->*counter
== 0)
171 (*hit_count
) += race
->*counter
;
173 for (; i
< matched
->Size(); i
++) {
174 ExpectRace
*race0
= &(*matched
)[i
];
175 if (race
->line
== race0
->line
176 && internal_strcmp(race
->file
, race0
->file
) == 0
177 && internal_strcmp(race
->desc
, race0
->desc
) == 0) {
178 race0
->*counter
+= race
->*counter
;
182 if (i
== matched
->Size())
183 matched
->PushBack(*race
);
187 void PrintMatchedBenignRaces() {
188 Lock
lock(&dyn_ann_ctx
->mtx
);
189 int unique_count
= 0;
192 Vector
<ExpectRace
> hit_matched(MBlockScopedBuf
);
193 CollectMatchedBenignRaces(&hit_matched
, &unique_count
, &hit_count
,
194 &ExpectRace::hitcount
);
195 Vector
<ExpectRace
> add_matched(MBlockScopedBuf
);
196 CollectMatchedBenignRaces(&add_matched
, &unique_count
, &add_count
,
197 &ExpectRace::addcount
);
198 if (hit_matched
.Size()) {
199 Printf("ThreadSanitizer: Matched %d \"benign\" races (pid=%d):\n",
200 hit_count
, (int)internal_getpid());
201 for (uptr i
= 0; i
< hit_matched
.Size(); i
++) {
202 Printf("%d %s:%d %s\n",
203 hit_matched
[i
].hitcount
, hit_matched
[i
].file
,
204 hit_matched
[i
].line
, hit_matched
[i
].desc
);
207 if (hit_matched
.Size()) {
208 Printf("ThreadSanitizer: Annotated %d \"benign\" races, %d unique"
210 add_count
, unique_count
, (int)internal_getpid());
211 for (uptr i
= 0; i
< add_matched
.Size(); i
++) {
212 Printf("%d %s:%d %s\n",
213 add_matched
[i
].addcount
, add_matched
[i
].file
,
214 add_matched
[i
].line
, add_matched
[i
].desc
);
219 static void ReportMissedExpectedRace(ExpectRace
*race
) {
220 Printf("==================\n");
221 Printf("WARNING: ThreadSanitizer: missed expected data race\n");
222 Printf(" %s addr=%zx %s:%d\n",
223 race
->desc
, race
->addr
, race
->file
, race
->line
);
224 Printf("==================\n");
226 } // namespace __tsan
228 using namespace __tsan
; // NOLINT
231 void INTERFACE_ATTRIBUTE
AnnotateHappensBefore(char *f
, int l
, uptr addr
) {
232 SCOPED_ANNOTATION(AnnotateHappensBefore
);
233 Release(thr
, pc
, addr
);
236 void INTERFACE_ATTRIBUTE
AnnotateHappensAfter(char *f
, int l
, uptr addr
) {
237 SCOPED_ANNOTATION(AnnotateHappensAfter
);
238 Acquire(thr
, pc
, addr
);
241 void INTERFACE_ATTRIBUTE
AnnotateCondVarSignal(char *f
, int l
, uptr cv
) {
242 SCOPED_ANNOTATION(AnnotateCondVarSignal
);
245 void INTERFACE_ATTRIBUTE
AnnotateCondVarSignalAll(char *f
, int l
, uptr cv
) {
246 SCOPED_ANNOTATION(AnnotateCondVarSignalAll
);
249 void INTERFACE_ATTRIBUTE
AnnotateMutexIsNotPHB(char *f
, int l
, uptr mu
) {
250 SCOPED_ANNOTATION(AnnotateMutexIsNotPHB
);
253 void INTERFACE_ATTRIBUTE
AnnotateCondVarWait(char *f
, int l
, uptr cv
,
255 SCOPED_ANNOTATION(AnnotateCondVarWait
);
258 void INTERFACE_ATTRIBUTE
AnnotateRWLockCreate(char *f
, int l
, uptr m
) {
259 SCOPED_ANNOTATION(AnnotateRWLockCreate
);
260 MutexCreate(thr
, pc
, m
, true, true, false);
263 void INTERFACE_ATTRIBUTE
AnnotateRWLockCreateStatic(char *f
, int l
, uptr m
) {
264 SCOPED_ANNOTATION(AnnotateRWLockCreateStatic
);
265 MutexCreate(thr
, pc
, m
, true, true, true);
268 void INTERFACE_ATTRIBUTE
AnnotateRWLockDestroy(char *f
, int l
, uptr m
) {
269 SCOPED_ANNOTATION(AnnotateRWLockDestroy
);
270 MutexDestroy(thr
, pc
, m
);
273 void INTERFACE_ATTRIBUTE
AnnotateRWLockAcquired(char *f
, int l
, uptr m
,
275 SCOPED_ANNOTATION(AnnotateRWLockAcquired
);
277 MutexLock(thr
, pc
, m
);
279 MutexReadLock(thr
, pc
, m
);
282 void INTERFACE_ATTRIBUTE
AnnotateRWLockReleased(char *f
, int l
, uptr m
,
284 SCOPED_ANNOTATION(AnnotateRWLockReleased
);
286 MutexUnlock(thr
, pc
, m
);
288 MutexReadUnlock(thr
, pc
, m
);
291 void INTERFACE_ATTRIBUTE
AnnotateTraceMemory(char *f
, int l
, uptr mem
) {
292 SCOPED_ANNOTATION(AnnotateTraceMemory
);
295 void INTERFACE_ATTRIBUTE
AnnotateFlushState(char *f
, int l
) {
296 SCOPED_ANNOTATION(AnnotateFlushState
);
299 void INTERFACE_ATTRIBUTE
AnnotateNewMemory(char *f
, int l
, uptr mem
,
301 SCOPED_ANNOTATION(AnnotateNewMemory
);
304 void INTERFACE_ATTRIBUTE
AnnotateNoOp(char *f
, int l
, uptr mem
) {
305 SCOPED_ANNOTATION(AnnotateNoOp
);
308 void INTERFACE_ATTRIBUTE
AnnotateFlushExpectedRaces(char *f
, int l
) {
309 SCOPED_ANNOTATION(AnnotateFlushExpectedRaces
);
310 Lock
lock(&dyn_ann_ctx
->mtx
);
311 while (dyn_ann_ctx
->expect
.next
!= &dyn_ann_ctx
->expect
) {
312 ExpectRace
*race
= dyn_ann_ctx
->expect
.next
;
313 if (race
->hitcount
== 0) {
314 CTX()->nmissed_expected
++;
315 ReportMissedExpectedRace(race
);
317 race
->prev
->next
= race
->next
;
318 race
->next
->prev
= race
->prev
;
323 void INTERFACE_ATTRIBUTE
AnnotateEnableRaceDetection(
324 char *f
, int l
, int enable
) {
325 SCOPED_ANNOTATION(AnnotateEnableRaceDetection
);
326 // FIXME: Reconsider this functionality later. It may be irrelevant.
329 void INTERFACE_ATTRIBUTE
AnnotateMutexIsUsedAsCondVar(
330 char *f
, int l
, uptr mu
) {
331 SCOPED_ANNOTATION(AnnotateMutexIsUsedAsCondVar
);
334 void INTERFACE_ATTRIBUTE
AnnotatePCQGet(
335 char *f
, int l
, uptr pcq
) {
336 SCOPED_ANNOTATION(AnnotatePCQGet
);
339 void INTERFACE_ATTRIBUTE
AnnotatePCQPut(
340 char *f
, int l
, uptr pcq
) {
341 SCOPED_ANNOTATION(AnnotatePCQPut
);
344 void INTERFACE_ATTRIBUTE
AnnotatePCQDestroy(
345 char *f
, int l
, uptr pcq
) {
346 SCOPED_ANNOTATION(AnnotatePCQDestroy
);
349 void INTERFACE_ATTRIBUTE
AnnotatePCQCreate(
350 char *f
, int l
, uptr pcq
) {
351 SCOPED_ANNOTATION(AnnotatePCQCreate
);
354 void INTERFACE_ATTRIBUTE
AnnotateExpectRace(
355 char *f
, int l
, uptr mem
, char *desc
) {
356 SCOPED_ANNOTATION(AnnotateExpectRace
);
357 Lock
lock(&dyn_ann_ctx
->mtx
);
358 AddExpectRace(&dyn_ann_ctx
->expect
,
360 DPrintf("Add expected race: %s addr=%zx %s:%d\n", desc
, mem
, f
, l
);
363 static void BenignRaceImpl(
364 char *f
, int l
, uptr mem
, uptr size
, char *desc
) {
365 Lock
lock(&dyn_ann_ctx
->mtx
);
366 AddExpectRace(&dyn_ann_ctx
->benign
,
367 f
, l
, mem
, size
, desc
);
368 DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc
, mem
, f
, l
);
371 // FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm.
372 void INTERFACE_ATTRIBUTE
AnnotateBenignRaceSized(
373 char *f
, int l
, uptr mem
, uptr size
, char *desc
) {
374 SCOPED_ANNOTATION(AnnotateBenignRaceSized
);
375 BenignRaceImpl(f
, l
, mem
, size
, desc
);
378 void INTERFACE_ATTRIBUTE
AnnotateBenignRace(
379 char *f
, int l
, uptr mem
, char *desc
) {
380 SCOPED_ANNOTATION(AnnotateBenignRace
);
381 BenignRaceImpl(f
, l
, mem
, 1, desc
);
384 void INTERFACE_ATTRIBUTE
AnnotateIgnoreReadsBegin(char *f
, int l
) {
385 SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin
);
386 ThreadIgnoreBegin(thr
, pc
);
389 void INTERFACE_ATTRIBUTE
AnnotateIgnoreReadsEnd(char *f
, int l
) {
390 SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd
);
391 ThreadIgnoreEnd(thr
, pc
);
394 void INTERFACE_ATTRIBUTE
AnnotateIgnoreWritesBegin(char *f
, int l
) {
395 SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin
);
396 ThreadIgnoreBegin(thr
, pc
);
399 void INTERFACE_ATTRIBUTE
AnnotateIgnoreWritesEnd(char *f
, int l
) {
400 SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd
);
401 ThreadIgnoreEnd(thr
, pc
);
404 void INTERFACE_ATTRIBUTE
AnnotateIgnoreSyncBegin(char *f
, int l
) {
405 SCOPED_ANNOTATION(AnnotateIgnoreSyncBegin
);
406 ThreadIgnoreSyncBegin(thr
, pc
);
409 void INTERFACE_ATTRIBUTE
AnnotateIgnoreSyncEnd(char *f
, int l
) {
410 SCOPED_ANNOTATION(AnnotateIgnoreSyncEnd
);
411 ThreadIgnoreSyncEnd(thr
, pc
);
414 void INTERFACE_ATTRIBUTE
AnnotatePublishMemoryRange(
415 char *f
, int l
, uptr addr
, uptr size
) {
416 SCOPED_ANNOTATION(AnnotatePublishMemoryRange
);
419 void INTERFACE_ATTRIBUTE
AnnotateUnpublishMemoryRange(
420 char *f
, int l
, uptr addr
, uptr size
) {
421 SCOPED_ANNOTATION(AnnotateUnpublishMemoryRange
);
424 void INTERFACE_ATTRIBUTE
AnnotateThreadName(
425 char *f
, int l
, char *name
) {
426 SCOPED_ANNOTATION(AnnotateThreadName
);
427 ThreadSetName(thr
, name
);
430 // We deliberately omit the implementation of WTFAnnotateHappensBefore() and
431 // WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate
432 // atomic operations, which should be handled by ThreadSanitizer correctly.
433 void INTERFACE_ATTRIBUTE
WTFAnnotateHappensBefore(char *f
, int l
, uptr addr
) {
434 SCOPED_ANNOTATION(AnnotateHappensBefore
);
437 void INTERFACE_ATTRIBUTE
WTFAnnotateHappensAfter(char *f
, int l
, uptr addr
) {
438 SCOPED_ANNOTATION(AnnotateHappensAfter
);
441 void INTERFACE_ATTRIBUTE
WTFAnnotateBenignRaceSized(
442 char *f
, int l
, uptr mem
, uptr sz
, char *desc
) {
443 SCOPED_ANNOTATION(AnnotateBenignRaceSized
);
444 BenignRaceImpl(f
, l
, mem
, sz
, desc
);
447 int INTERFACE_ATTRIBUTE
RunningOnValgrind() {
448 return flags()->running_on_valgrind
;
451 double __attribute__((weak
)) INTERFACE_ATTRIBUTE
ValgrindSlowdown(void) {
455 const char INTERFACE_ATTRIBUTE
* ThreadSanitizerQuery(const char *query
) {
456 if (internal_strcmp(query
, "pure_happens_before") == 0)
462 void INTERFACE_ATTRIBUTE
463 AnnotateMemoryIsInitialized(char *f
, int l
, uptr mem
, uptr sz
) {}