1 //===-- tsan_interface_ann.cc ---------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
10 //===----------------------------------------------------------------------===//
11 #include "sanitizer_common/sanitizer_libc.h"
12 #include "sanitizer_common/sanitizer_internal_defs.h"
13 #include "sanitizer_common/sanitizer_placement_new.h"
14 #include "tsan_interface_ann.h"
15 #include "tsan_mutex.h"
16 #include "tsan_report.h"
18 #include "tsan_mman.h"
19 #include "tsan_flags.h"
20 #include "tsan_platform.h"
22 #define CALLERPC ((uptr)__builtin_return_address(0))
24 using namespace __tsan
; // NOLINT
28 class ScopedAnnotation
{
30 ScopedAnnotation(ThreadState
*thr
, const char *aname
, const char *f
, int l
,
33 , in_rtl_(thr
->in_rtl
) {
34 CHECK_EQ(thr_
->in_rtl
, 0);
37 DPrintf("#%d: annotation %s() %s:%d\n", thr_
->tid
, aname
, f
, l
);
42 CHECK_EQ(in_rtl_
, thr_
->in_rtl
);
46 ThreadState
*const thr_
;
50 #define SCOPED_ANNOTATION(typ) \
51 if (!flags()->enable_annotations) \
53 ThreadState *thr = cur_thread(); \
54 const uptr pc = (uptr)__builtin_return_address(0); \
55 StatInc(thr, StatAnnotation); \
56 StatInc(thr, Stat##typ); \
57 ScopedAnnotation sa(thr, __FUNCTION__, f, l, \
58 (uptr)__builtin_return_address(0)); \
62 static const int kMaxDescLen
= 128;
72 char desc
[kMaxDescLen
];
75 struct DynamicAnnContext
{
81 : mtx(MutexTypeAnnotations
, StatMtxAnnotations
) {
85 static DynamicAnnContext
*dyn_ann_ctx
;
86 static char dyn_ann_ctx_placeholder
[sizeof(DynamicAnnContext
)] ALIGNED(64);
88 static void AddExpectRace(ExpectRace
*list
,
89 char *f
, int l
, uptr addr
, uptr size
, char *desc
) {
90 ExpectRace
*race
= list
->next
;
91 for (; race
!= list
; race
= race
->next
) {
92 if (race
->addr
== addr
&& race
->size
== size
)
95 race
= (ExpectRace
*)internal_alloc(MBlockExpectRace
, sizeof(ExpectRace
));
104 for (; i
< kMaxDescLen
- 1 && desc
[i
]; i
++)
105 race
->desc
[i
] = desc
[i
];
109 race
->next
= list
->next
;
110 race
->next
->prev
= race
;
114 static ExpectRace
*FindRace(ExpectRace
*list
, uptr addr
, uptr size
) {
115 for (ExpectRace
*race
= list
->next
; race
!= list
; race
= race
->next
) {
116 uptr maxbegin
= max(race
->addr
, addr
);
117 uptr minend
= min(race
->addr
+ race
->size
, addr
+ size
);
118 if (maxbegin
< minend
)
124 static bool CheckContains(ExpectRace
*list
, uptr addr
, uptr size
) {
125 ExpectRace
*race
= FindRace(list
, addr
, size
);
126 if (race
== 0 && AlternativeAddress(addr
))
127 race
= FindRace(list
, AlternativeAddress(addr
), size
);
130 DPrintf("Hit expected/benign race: %s addr=%zx:%d %s:%d\n",
131 race
->desc
, race
->addr
, (int)race
->size
, race
->file
, race
->line
);
136 static void InitList(ExpectRace
*list
) {
141 void InitializeDynamicAnnotations() {
142 dyn_ann_ctx
= new(dyn_ann_ctx_placeholder
) DynamicAnnContext
;
143 InitList(&dyn_ann_ctx
->expect
);
144 InitList(&dyn_ann_ctx
->benign
);
147 bool IsExpectedReport(uptr addr
, uptr size
) {
148 Lock
lock(&dyn_ann_ctx
->mtx
);
149 if (CheckContains(&dyn_ann_ctx
->expect
, addr
, size
))
151 if (CheckContains(&dyn_ann_ctx
->benign
, addr
, size
))
156 } // namespace __tsan
158 using namespace __tsan
; // NOLINT
161 void INTERFACE_ATTRIBUTE
AnnotateHappensBefore(char *f
, int l
, uptr addr
) {
162 SCOPED_ANNOTATION(AnnotateHappensBefore
);
163 Release(cur_thread(), CALLERPC
, addr
);
166 void INTERFACE_ATTRIBUTE
AnnotateHappensAfter(char *f
, int l
, uptr addr
) {
167 SCOPED_ANNOTATION(AnnotateHappensAfter
);
168 Acquire(cur_thread(), CALLERPC
, addr
);
171 void INTERFACE_ATTRIBUTE
AnnotateCondVarSignal(char *f
, int l
, uptr cv
) {
172 SCOPED_ANNOTATION(AnnotateCondVarSignal
);
175 void INTERFACE_ATTRIBUTE
AnnotateCondVarSignalAll(char *f
, int l
, uptr cv
) {
176 SCOPED_ANNOTATION(AnnotateCondVarSignalAll
);
179 void INTERFACE_ATTRIBUTE
AnnotateMutexIsNotPHB(char *f
, int l
, uptr mu
) {
180 SCOPED_ANNOTATION(AnnotateMutexIsNotPHB
);
183 void INTERFACE_ATTRIBUTE
AnnotateCondVarWait(char *f
, int l
, uptr cv
,
185 SCOPED_ANNOTATION(AnnotateCondVarWait
);
188 void INTERFACE_ATTRIBUTE
AnnotateRWLockCreate(char *f
, int l
, uptr m
) {
189 SCOPED_ANNOTATION(AnnotateRWLockCreate
);
190 MutexCreate(thr
, pc
, m
, true, true, false);
193 void INTERFACE_ATTRIBUTE
AnnotateRWLockCreateStatic(char *f
, int l
, uptr m
) {
194 SCOPED_ANNOTATION(AnnotateRWLockCreateStatic
);
195 MutexCreate(thr
, pc
, m
, true, true, true);
198 void INTERFACE_ATTRIBUTE
AnnotateRWLockDestroy(char *f
, int l
, uptr m
) {
199 SCOPED_ANNOTATION(AnnotateRWLockDestroy
);
200 MutexDestroy(thr
, pc
, m
);
203 void INTERFACE_ATTRIBUTE
AnnotateRWLockAcquired(char *f
, int l
, uptr m
,
205 SCOPED_ANNOTATION(AnnotateRWLockAcquired
);
207 MutexLock(thr
, pc
, m
);
209 MutexReadLock(thr
, pc
, m
);
212 void INTERFACE_ATTRIBUTE
AnnotateRWLockReleased(char *f
, int l
, uptr m
,
214 SCOPED_ANNOTATION(AnnotateRWLockReleased
);
216 MutexUnlock(thr
, pc
, m
);
218 MutexReadUnlock(thr
, pc
, m
);
221 void INTERFACE_ATTRIBUTE
AnnotateTraceMemory(char *f
, int l
, uptr mem
) {
222 SCOPED_ANNOTATION(AnnotateTraceMemory
);
225 void INTERFACE_ATTRIBUTE
AnnotateFlushState(char *f
, int l
) {
226 SCOPED_ANNOTATION(AnnotateFlushState
);
229 void INTERFACE_ATTRIBUTE
AnnotateNewMemory(char *f
, int l
, uptr mem
,
231 SCOPED_ANNOTATION(AnnotateNewMemory
);
234 void INTERFACE_ATTRIBUTE
AnnotateNoOp(char *f
, int l
, uptr mem
) {
235 SCOPED_ANNOTATION(AnnotateNoOp
);
238 static void ReportMissedExpectedRace(ExpectRace
*race
) {
239 Printf("==================\n");
240 Printf("WARNING: ThreadSanitizer: missed expected data race\n");
241 Printf(" %s addr=%zx %s:%d\n",
242 race
->desc
, race
->addr
, race
->file
, race
->line
);
243 Printf("==================\n");
246 void INTERFACE_ATTRIBUTE
AnnotateFlushExpectedRaces(char *f
, int l
) {
247 SCOPED_ANNOTATION(AnnotateFlushExpectedRaces
);
248 Lock
lock(&dyn_ann_ctx
->mtx
);
249 while (dyn_ann_ctx
->expect
.next
!= &dyn_ann_ctx
->expect
) {
250 ExpectRace
*race
= dyn_ann_ctx
->expect
.next
;
251 if (race
->hitcount
== 0) {
252 CTX()->nmissed_expected
++;
253 ReportMissedExpectedRace(race
);
255 race
->prev
->next
= race
->next
;
256 race
->next
->prev
= race
->prev
;
261 void INTERFACE_ATTRIBUTE
AnnotateEnableRaceDetection(
262 char *f
, int l
, int enable
) {
263 SCOPED_ANNOTATION(AnnotateEnableRaceDetection
);
264 // FIXME: Reconsider this functionality later. It may be irrelevant.
267 void INTERFACE_ATTRIBUTE
AnnotateMutexIsUsedAsCondVar(
268 char *f
, int l
, uptr mu
) {
269 SCOPED_ANNOTATION(AnnotateMutexIsUsedAsCondVar
);
272 void INTERFACE_ATTRIBUTE
AnnotatePCQGet(
273 char *f
, int l
, uptr pcq
) {
274 SCOPED_ANNOTATION(AnnotatePCQGet
);
277 void INTERFACE_ATTRIBUTE
AnnotatePCQPut(
278 char *f
, int l
, uptr pcq
) {
279 SCOPED_ANNOTATION(AnnotatePCQPut
);
282 void INTERFACE_ATTRIBUTE
AnnotatePCQDestroy(
283 char *f
, int l
, uptr pcq
) {
284 SCOPED_ANNOTATION(AnnotatePCQDestroy
);
287 void INTERFACE_ATTRIBUTE
AnnotatePCQCreate(
288 char *f
, int l
, uptr pcq
) {
289 SCOPED_ANNOTATION(AnnotatePCQCreate
);
292 void INTERFACE_ATTRIBUTE
AnnotateExpectRace(
293 char *f
, int l
, uptr mem
, char *desc
) {
294 SCOPED_ANNOTATION(AnnotateExpectRace
);
295 Lock
lock(&dyn_ann_ctx
->mtx
);
296 AddExpectRace(&dyn_ann_ctx
->expect
,
298 DPrintf("Add expected race: %s addr=%zx %s:%d\n", desc
, mem
, f
, l
);
301 static void BenignRaceImpl(
302 char *f
, int l
, uptr mem
, uptr size
, char *desc
) {
303 Lock
lock(&dyn_ann_ctx
->mtx
);
304 AddExpectRace(&dyn_ann_ctx
->benign
,
305 f
, l
, mem
, size
, desc
);
306 DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc
, mem
, f
, l
);
309 // FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm.
310 void INTERFACE_ATTRIBUTE
AnnotateBenignRaceSized(
311 char *f
, int l
, uptr mem
, uptr size
, char *desc
) {
312 SCOPED_ANNOTATION(AnnotateBenignRaceSized
);
313 BenignRaceImpl(f
, l
, mem
, size
, desc
);
316 void INTERFACE_ATTRIBUTE
AnnotateBenignRace(
317 char *f
, int l
, uptr mem
, char *desc
) {
318 SCOPED_ANNOTATION(AnnotateBenignRace
);
319 BenignRaceImpl(f
, l
, mem
, 1, desc
);
322 void INTERFACE_ATTRIBUTE
AnnotateIgnoreReadsBegin(char *f
, int l
) {
323 SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin
);
324 IgnoreCtl(cur_thread(), false, true);
327 void INTERFACE_ATTRIBUTE
AnnotateIgnoreReadsEnd(char *f
, int l
) {
328 SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd
);
329 IgnoreCtl(cur_thread(), false, false);
332 void INTERFACE_ATTRIBUTE
AnnotateIgnoreWritesBegin(char *f
, int l
) {
333 SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin
);
334 IgnoreCtl(cur_thread(), true, true);
337 void INTERFACE_ATTRIBUTE
AnnotateIgnoreWritesEnd(char *f
, int l
) {
338 SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd
);
339 IgnoreCtl(thr
, true, false);
342 void INTERFACE_ATTRIBUTE
AnnotatePublishMemoryRange(
343 char *f
, int l
, uptr addr
, uptr size
) {
344 SCOPED_ANNOTATION(AnnotatePublishMemoryRange
);
347 void INTERFACE_ATTRIBUTE
AnnotateUnpublishMemoryRange(
348 char *f
, int l
, uptr addr
, uptr size
) {
349 SCOPED_ANNOTATION(AnnotateUnpublishMemoryRange
);
352 void INTERFACE_ATTRIBUTE
AnnotateThreadName(
353 char *f
, int l
, char *name
) {
354 SCOPED_ANNOTATION(AnnotateThreadName
);
355 ThreadSetName(thr
, name
);
358 void INTERFACE_ATTRIBUTE
WTFAnnotateHappensBefore(char *f
, int l
, uptr addr
) {
359 SCOPED_ANNOTATION(AnnotateHappensBefore
);
362 void INTERFACE_ATTRIBUTE
WTFAnnotateHappensAfter(char *f
, int l
, uptr addr
) {
363 SCOPED_ANNOTATION(AnnotateHappensAfter
);
366 void INTERFACE_ATTRIBUTE
WTFAnnotateBenignRaceSized(
367 char *f
, int l
, uptr mem
, uptr sz
, char *desc
) {
368 SCOPED_ANNOTATION(AnnotateBenignRaceSized
);
371 int INTERFACE_ATTRIBUTE
RunningOnValgrind() {
372 return flags()->running_on_valgrind
;
375 double __attribute__((weak
)) INTERFACE_ATTRIBUTE
ValgrindSlowdown(void) {
379 const char INTERFACE_ATTRIBUTE
* ThreadSanitizerQuery(const char *query
) {
380 if (internal_strcmp(query
, "pure_happens_before") == 0)