Daily bump.
[official-gcc.git] / libsanitizer / tsan / tsan_interface_ann.cc
blob20e3d9a35ac7c4f03f85bb9e891d9a8829bc379f
1 //===-- tsan_interface_ann.cc ---------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
9 //
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 "sanitizer_common/sanitizer_stacktrace.h"
15 #include "tsan_interface_ann.h"
16 #include "tsan_mutex.h"
17 #include "tsan_report.h"
18 #include "tsan_rtl.h"
19 #include "tsan_mman.h"
20 #include "tsan_flags.h"
21 #include "tsan_platform.h"
22 #include "tsan_vector.h"
24 #define CALLERPC ((uptr)__builtin_return_address(0))
26 using namespace __tsan; // NOLINT
28 namespace __tsan {
30 class ScopedAnnotation {
31 public:
32 ScopedAnnotation(ThreadState *thr, const char *aname, const char *f, int l,
33 uptr pc)
34 : thr_(thr) {
35 FuncEntry(thr_, pc);
36 DPrintf("#%d: annotation %s() %s:%d\n", thr_->tid, aname, f, l);
39 ~ScopedAnnotation() {
40 FuncExit(thr_);
42 private:
43 ThreadState *const thr_;
46 #define SCOPED_ANNOTATION(typ) \
47 if (!flags()->enable_annotations) \
48 return; \
49 ThreadState *thr = cur_thread(); \
50 const uptr caller_pc = (uptr)__builtin_return_address(0); \
51 StatInc(thr, StatAnnotation); \
52 StatInc(thr, Stat##typ); \
53 ScopedAnnotation sa(thr, __func__, f, l, caller_pc); \
54 const uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
55 (void)pc; \
56 /**/
58 static const int kMaxDescLen = 128;
60 struct ExpectRace {
61 ExpectRace *next;
62 ExpectRace *prev;
63 int hitcount;
64 int addcount;
65 uptr addr;
66 uptr size;
67 char *file;
68 int line;
69 char desc[kMaxDescLen];
72 struct DynamicAnnContext {
73 Mutex mtx;
74 ExpectRace expect;
75 ExpectRace benign;
77 DynamicAnnContext()
78 : mtx(MutexTypeAnnotations, StatMtxAnnotations) {
82 static DynamicAnnContext *dyn_ann_ctx;
83 static char dyn_ann_ctx_placeholder[sizeof(DynamicAnnContext)] ALIGNED(64);
85 static void AddExpectRace(ExpectRace *list,
86 char *f, int l, uptr addr, uptr size, char *desc) {
87 ExpectRace *race = list->next;
88 for (; race != list; race = race->next) {
89 if (race->addr == addr && race->size == size) {
90 race->addcount++;
91 return;
94 race = (ExpectRace*)internal_alloc(MBlockExpectRace, sizeof(ExpectRace));
95 race->addr = addr;
96 race->size = size;
97 race->file = f;
98 race->line = l;
99 race->desc[0] = 0;
100 race->hitcount = 0;
101 race->addcount = 1;
102 if (desc) {
103 int i = 0;
104 for (; i < kMaxDescLen - 1 && desc[i]; i++)
105 race->desc[i] = desc[i];
106 race->desc[i] = 0;
108 race->prev = list;
109 race->next = list->next;
110 race->next->prev = race;
111 list->next = 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)
119 return race;
121 return 0;
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);
128 if (race == 0)
129 return false;
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);
132 race->hitcount++;
133 return true;
136 static void InitList(ExpectRace *list) {
137 list->next = list;
138 list->prev = 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))
150 return true;
151 if (CheckContains(&dyn_ann_ctx->benign, addr, size))
152 return true;
153 return false;
156 static void CollectMatchedBenignRaces(Vector<ExpectRace> *matched,
157 int *unique_count, int *hit_count, int ExpectRace::*counter) {
158 ExpectRace *list = &dyn_ann_ctx->benign;
159 for (ExpectRace *race = list->next; race != list; race = race->next) {
160 (*unique_count)++;
161 if (race->*counter == 0)
162 continue;
163 (*hit_count) += race->*counter;
164 uptr i = 0;
165 for (; i < matched->Size(); i++) {
166 ExpectRace *race0 = &(*matched)[i];
167 if (race->line == race0->line
168 && internal_strcmp(race->file, race0->file) == 0
169 && internal_strcmp(race->desc, race0->desc) == 0) {
170 race0->*counter += race->*counter;
171 break;
174 if (i == matched->Size())
175 matched->PushBack(*race);
179 void PrintMatchedBenignRaces() {
180 Lock lock(&dyn_ann_ctx->mtx);
181 int unique_count = 0;
182 int hit_count = 0;
183 int add_count = 0;
184 Vector<ExpectRace> hit_matched(MBlockScopedBuf);
185 CollectMatchedBenignRaces(&hit_matched, &unique_count, &hit_count,
186 &ExpectRace::hitcount);
187 Vector<ExpectRace> add_matched(MBlockScopedBuf);
188 CollectMatchedBenignRaces(&add_matched, &unique_count, &add_count,
189 &ExpectRace::addcount);
190 if (hit_matched.Size()) {
191 Printf("ThreadSanitizer: Matched %d \"benign\" races (pid=%d):\n",
192 hit_count, (int)internal_getpid());
193 for (uptr i = 0; i < hit_matched.Size(); i++) {
194 Printf("%d %s:%d %s\n",
195 hit_matched[i].hitcount, hit_matched[i].file,
196 hit_matched[i].line, hit_matched[i].desc);
199 if (hit_matched.Size()) {
200 Printf("ThreadSanitizer: Annotated %d \"benign\" races, %d unique"
201 " (pid=%d):\n",
202 add_count, unique_count, (int)internal_getpid());
203 for (uptr i = 0; i < add_matched.Size(); i++) {
204 Printf("%d %s:%d %s\n",
205 add_matched[i].addcount, add_matched[i].file,
206 add_matched[i].line, add_matched[i].desc);
211 static void ReportMissedExpectedRace(ExpectRace *race) {
212 Printf("==================\n");
213 Printf("WARNING: ThreadSanitizer: missed expected data race\n");
214 Printf(" %s addr=%zx %s:%d\n",
215 race->desc, race->addr, race->file, race->line);
216 Printf("==================\n");
218 } // namespace __tsan
220 using namespace __tsan; // NOLINT
222 extern "C" {
223 void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {
224 SCOPED_ANNOTATION(AnnotateHappensBefore);
225 Release(thr, pc, addr);
228 void INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {
229 SCOPED_ANNOTATION(AnnotateHappensAfter);
230 Acquire(thr, pc, addr);
233 void INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {
234 SCOPED_ANNOTATION(AnnotateCondVarSignal);
237 void INTERFACE_ATTRIBUTE AnnotateCondVarSignalAll(char *f, int l, uptr cv) {
238 SCOPED_ANNOTATION(AnnotateCondVarSignalAll);
241 void INTERFACE_ATTRIBUTE AnnotateMutexIsNotPHB(char *f, int l, uptr mu) {
242 SCOPED_ANNOTATION(AnnotateMutexIsNotPHB);
245 void INTERFACE_ATTRIBUTE AnnotateCondVarWait(char *f, int l, uptr cv,
246 uptr lock) {
247 SCOPED_ANNOTATION(AnnotateCondVarWait);
250 void INTERFACE_ATTRIBUTE AnnotateRWLockCreate(char *f, int l, uptr m) {
251 SCOPED_ANNOTATION(AnnotateRWLockCreate);
252 MutexCreate(thr, pc, m, true, true, false);
255 void INTERFACE_ATTRIBUTE AnnotateRWLockCreateStatic(char *f, int l, uptr m) {
256 SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);
257 MutexCreate(thr, pc, m, true, true, true);
260 void INTERFACE_ATTRIBUTE AnnotateRWLockDestroy(char *f, int l, uptr m) {
261 SCOPED_ANNOTATION(AnnotateRWLockDestroy);
262 MutexDestroy(thr, pc, m);
265 void INTERFACE_ATTRIBUTE AnnotateRWLockAcquired(char *f, int l, uptr m,
266 uptr is_w) {
267 SCOPED_ANNOTATION(AnnotateRWLockAcquired);
268 if (is_w)
269 MutexLock(thr, pc, m);
270 else
271 MutexReadLock(thr, pc, m);
274 void INTERFACE_ATTRIBUTE AnnotateRWLockReleased(char *f, int l, uptr m,
275 uptr is_w) {
276 SCOPED_ANNOTATION(AnnotateRWLockReleased);
277 if (is_w)
278 MutexUnlock(thr, pc, m);
279 else
280 MutexReadUnlock(thr, pc, m);
283 void INTERFACE_ATTRIBUTE AnnotateTraceMemory(char *f, int l, uptr mem) {
284 SCOPED_ANNOTATION(AnnotateTraceMemory);
287 void INTERFACE_ATTRIBUTE AnnotateFlushState(char *f, int l) {
288 SCOPED_ANNOTATION(AnnotateFlushState);
291 void INTERFACE_ATTRIBUTE AnnotateNewMemory(char *f, int l, uptr mem,
292 uptr size) {
293 SCOPED_ANNOTATION(AnnotateNewMemory);
296 void INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {
297 SCOPED_ANNOTATION(AnnotateNoOp);
300 void INTERFACE_ATTRIBUTE AnnotateFlushExpectedRaces(char *f, int l) {
301 SCOPED_ANNOTATION(AnnotateFlushExpectedRaces);
302 Lock lock(&dyn_ann_ctx->mtx);
303 while (dyn_ann_ctx->expect.next != &dyn_ann_ctx->expect) {
304 ExpectRace *race = dyn_ann_ctx->expect.next;
305 if (race->hitcount == 0) {
306 ctx->nmissed_expected++;
307 ReportMissedExpectedRace(race);
309 race->prev->next = race->next;
310 race->next->prev = race->prev;
311 internal_free(race);
315 void INTERFACE_ATTRIBUTE AnnotateEnableRaceDetection(
316 char *f, int l, int enable) {
317 SCOPED_ANNOTATION(AnnotateEnableRaceDetection);
318 // FIXME: Reconsider this functionality later. It may be irrelevant.
321 void INTERFACE_ATTRIBUTE AnnotateMutexIsUsedAsCondVar(
322 char *f, int l, uptr mu) {
323 SCOPED_ANNOTATION(AnnotateMutexIsUsedAsCondVar);
326 void INTERFACE_ATTRIBUTE AnnotatePCQGet(
327 char *f, int l, uptr pcq) {
328 SCOPED_ANNOTATION(AnnotatePCQGet);
331 void INTERFACE_ATTRIBUTE AnnotatePCQPut(
332 char *f, int l, uptr pcq) {
333 SCOPED_ANNOTATION(AnnotatePCQPut);
336 void INTERFACE_ATTRIBUTE AnnotatePCQDestroy(
337 char *f, int l, uptr pcq) {
338 SCOPED_ANNOTATION(AnnotatePCQDestroy);
341 void INTERFACE_ATTRIBUTE AnnotatePCQCreate(
342 char *f, int l, uptr pcq) {
343 SCOPED_ANNOTATION(AnnotatePCQCreate);
346 void INTERFACE_ATTRIBUTE AnnotateExpectRace(
347 char *f, int l, uptr mem, char *desc) {
348 SCOPED_ANNOTATION(AnnotateExpectRace);
349 Lock lock(&dyn_ann_ctx->mtx);
350 AddExpectRace(&dyn_ann_ctx->expect,
351 f, l, mem, 1, desc);
352 DPrintf("Add expected race: %s addr=%zx %s:%d\n", desc, mem, f, l);
355 static void BenignRaceImpl(
356 char *f, int l, uptr mem, uptr size, char *desc) {
357 Lock lock(&dyn_ann_ctx->mtx);
358 AddExpectRace(&dyn_ann_ctx->benign,
359 f, l, mem, size, desc);
360 DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc, mem, f, l);
363 // FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm.
364 void INTERFACE_ATTRIBUTE AnnotateBenignRaceSized(
365 char *f, int l, uptr mem, uptr size, char *desc) {
366 SCOPED_ANNOTATION(AnnotateBenignRaceSized);
367 BenignRaceImpl(f, l, mem, size, desc);
370 void INTERFACE_ATTRIBUTE AnnotateBenignRace(
371 char *f, int l, uptr mem, char *desc) {
372 SCOPED_ANNOTATION(AnnotateBenignRace);
373 BenignRaceImpl(f, l, mem, 1, desc);
376 void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsBegin(char *f, int l) {
377 SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin);
378 ThreadIgnoreBegin(thr, pc);
381 void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsEnd(char *f, int l) {
382 SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd);
383 ThreadIgnoreEnd(thr, pc);
386 void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {
387 SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin);
388 ThreadIgnoreBegin(thr, pc);
391 void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {
392 SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);
393 ThreadIgnoreEnd(thr, pc);
396 void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncBegin(char *f, int l) {
397 SCOPED_ANNOTATION(AnnotateIgnoreSyncBegin);
398 ThreadIgnoreSyncBegin(thr, pc);
401 void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncEnd(char *f, int l) {
402 SCOPED_ANNOTATION(AnnotateIgnoreSyncEnd);
403 ThreadIgnoreSyncEnd(thr, pc);
406 void INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(
407 char *f, int l, uptr addr, uptr size) {
408 SCOPED_ANNOTATION(AnnotatePublishMemoryRange);
411 void INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(
412 char *f, int l, uptr addr, uptr size) {
413 SCOPED_ANNOTATION(AnnotateUnpublishMemoryRange);
416 void INTERFACE_ATTRIBUTE AnnotateThreadName(
417 char *f, int l, char *name) {
418 SCOPED_ANNOTATION(AnnotateThreadName);
419 ThreadSetName(thr, name);
422 // We deliberately omit the implementation of WTFAnnotateHappensBefore() and
423 // WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate
424 // atomic operations, which should be handled by ThreadSanitizer correctly.
425 void INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {
426 SCOPED_ANNOTATION(AnnotateHappensBefore);
429 void INTERFACE_ATTRIBUTE WTFAnnotateHappensAfter(char *f, int l, uptr addr) {
430 SCOPED_ANNOTATION(AnnotateHappensAfter);
433 void INTERFACE_ATTRIBUTE WTFAnnotateBenignRaceSized(
434 char *f, int l, uptr mem, uptr sz, char *desc) {
435 SCOPED_ANNOTATION(AnnotateBenignRaceSized);
436 BenignRaceImpl(f, l, mem, sz, desc);
439 int INTERFACE_ATTRIBUTE RunningOnValgrind() {
440 return flags()->running_on_valgrind;
443 double __attribute__((weak)) INTERFACE_ATTRIBUTE ValgrindSlowdown(void) {
444 return 10.0;
447 const char INTERFACE_ATTRIBUTE* ThreadSanitizerQuery(const char *query) {
448 if (internal_strcmp(query, "pure_happens_before") == 0)
449 return "1";
450 else
451 return "0";
454 void INTERFACE_ATTRIBUTE
455 AnnotateMemoryIsInitialized(char *f, int l, uptr mem, uptr sz) {}
456 } // extern "C"