]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cc
Upgrade our copy of clang and llvm to 3.5.1 release. This is a bugfix
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / tsan / rtl / tsan_interface_ann.cc
1 //===-- tsan_interface_ann.cc ---------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //
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"
20 #include "tsan_rtl.h"
21 #include "tsan_mman.h"
22 #include "tsan_flags.h"
23 #include "tsan_platform.h"
24 #include "tsan_vector.h"
25
26 #define CALLERPC ((uptr)__builtin_return_address(0))
27
28 using namespace __tsan;  // NOLINT
29
30 namespace __tsan {
31
32 class ScopedAnnotation {
33  public:
34   ScopedAnnotation(ThreadState *thr, const char *aname, const char *f, int l,
35                    uptr pc)
36       : thr_(thr) {
37     FuncEntry(thr_, pc);
38     DPrintf("#%d: annotation %s() %s:%d\n", thr_->tid, aname, f, l);
39   }
40
41   ~ScopedAnnotation() {
42     FuncExit(thr_);
43     CheckNoLocks(thr_);
44   }
45  private:
46   ThreadState *const thr_;
47 };
48
49 #define SCOPED_ANNOTATION(typ) \
50     if (!flags()->enable_annotations) \
51       return; \
52     ThreadState *thr = cur_thread(); \
53     const uptr caller_pc = (uptr)__builtin_return_address(0); \
54     StatInc(thr, StatAnnotation); \
55     StatInc(thr, Stat##typ); \
56     ScopedAnnotation sa(thr, __func__, f, l, caller_pc); \
57     const uptr pc = StackTrace::GetCurrentPc(); \
58     (void)pc; \
59 /**/
60
61 static const int kMaxDescLen = 128;
62
63 struct ExpectRace {
64   ExpectRace *next;
65   ExpectRace *prev;
66   int hitcount;
67   int addcount;
68   uptr addr;
69   uptr size;
70   char *file;
71   int line;
72   char desc[kMaxDescLen];
73 };
74
75 struct DynamicAnnContext {
76   Mutex mtx;
77   ExpectRace expect;
78   ExpectRace benign;
79
80   DynamicAnnContext()
81     : mtx(MutexTypeAnnotations, StatMtxAnnotations) {
82   }
83 };
84
85 static DynamicAnnContext *dyn_ann_ctx;
86 static char dyn_ann_ctx_placeholder[sizeof(DynamicAnnContext)] ALIGNED(64);
87
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) {
93       race->addcount++;
94       return;
95     }
96   }
97   race = (ExpectRace*)internal_alloc(MBlockExpectRace, sizeof(ExpectRace));
98   race->addr = addr;
99   race->size = size;
100   race->file = f;
101   race->line = l;
102   race->desc[0] = 0;
103   race->hitcount = 0;
104   race->addcount = 1;
105   if (desc) {
106     int i = 0;
107     for (; i < kMaxDescLen - 1 && desc[i]; i++)
108       race->desc[i] = desc[i];
109     race->desc[i] = 0;
110   }
111   race->prev = list;
112   race->next = list->next;
113   race->next->prev = race;
114   list->next = race;
115 }
116
117 static ExpectRace *FindRace(ExpectRace *list, uptr addr, uptr size) {
118   for (ExpectRace *race = list->next; race != list; race = race->next) {
119     uptr maxbegin = max(race->addr, addr);
120     uptr minend = min(race->addr + race->size, addr + size);
121     if (maxbegin < minend)
122       return race;
123   }
124   return 0;
125 }
126
127 static bool CheckContains(ExpectRace *list, uptr addr, uptr size) {
128   ExpectRace *race = FindRace(list, addr, size);
129   if (race == 0)
130     return false;
131   DPrintf("Hit expected/benign race: %s addr=%zx:%d %s:%d\n",
132       race->desc, race->addr, (int)race->size, race->file, race->line);
133   race->hitcount++;
134   return true;
135 }
136
137 static void InitList(ExpectRace *list) {
138   list->next = list;
139   list->prev = list;
140 }
141
142 void InitializeDynamicAnnotations() {
143   dyn_ann_ctx = new(dyn_ann_ctx_placeholder) DynamicAnnContext;
144   InitList(&dyn_ann_ctx->expect);
145   InitList(&dyn_ann_ctx->benign);
146 }
147
148 bool IsExpectedReport(uptr addr, uptr size) {
149   Lock lock(&dyn_ann_ctx->mtx);
150   if (CheckContains(&dyn_ann_ctx->expect, addr, size))
151     return true;
152   if (CheckContains(&dyn_ann_ctx->benign, addr, size))
153     return true;
154   return false;
155 }
156
157 static void CollectMatchedBenignRaces(Vector<ExpectRace> *matched,
158     int *unique_count, int *hit_count, int ExpectRace::*counter) {
159   ExpectRace *list = &dyn_ann_ctx->benign;
160   for (ExpectRace *race = list->next; race != list; race = race->next) {
161     (*unique_count)++;
162     if (race->*counter == 0)
163       continue;
164     (*hit_count) += race->*counter;
165     uptr i = 0;
166     for (; i < matched->Size(); i++) {
167       ExpectRace *race0 = &(*matched)[i];
168       if (race->line == race0->line
169           && internal_strcmp(race->file, race0->file) == 0
170           && internal_strcmp(race->desc, race0->desc) == 0) {
171         race0->*counter += race->*counter;
172         break;
173       }
174     }
175     if (i == matched->Size())
176       matched->PushBack(*race);
177   }
178 }
179
180 void PrintMatchedBenignRaces() {
181   Lock lock(&dyn_ann_ctx->mtx);
182   int unique_count = 0;
183   int hit_count = 0;
184   int add_count = 0;
185   Vector<ExpectRace> hit_matched(MBlockScopedBuf);
186   CollectMatchedBenignRaces(&hit_matched, &unique_count, &hit_count,
187       &ExpectRace::hitcount);
188   Vector<ExpectRace> add_matched(MBlockScopedBuf);
189   CollectMatchedBenignRaces(&add_matched, &unique_count, &add_count,
190       &ExpectRace::addcount);
191   if (hit_matched.Size()) {
192     Printf("ThreadSanitizer: Matched %d \"benign\" races (pid=%d):\n",
193         hit_count, (int)internal_getpid());
194     for (uptr i = 0; i < hit_matched.Size(); i++) {
195       Printf("%d %s:%d %s\n",
196           hit_matched[i].hitcount, hit_matched[i].file,
197           hit_matched[i].line, hit_matched[i].desc);
198     }
199   }
200   if (hit_matched.Size()) {
201     Printf("ThreadSanitizer: Annotated %d \"benign\" races, %d unique"
202            " (pid=%d):\n",
203         add_count, unique_count, (int)internal_getpid());
204     for (uptr i = 0; i < add_matched.Size(); i++) {
205       Printf("%d %s:%d %s\n",
206           add_matched[i].addcount, add_matched[i].file,
207           add_matched[i].line, add_matched[i].desc);
208     }
209   }
210 }
211
212 static void ReportMissedExpectedRace(ExpectRace *race) {
213   Printf("==================\n");
214   Printf("WARNING: ThreadSanitizer: missed expected data race\n");
215   Printf("  %s addr=%zx %s:%d\n",
216       race->desc, race->addr, race->file, race->line);
217   Printf("==================\n");
218 }
219 }  // namespace __tsan
220
221 using namespace __tsan;  // NOLINT
222
223 extern "C" {
224 void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {
225   SCOPED_ANNOTATION(AnnotateHappensBefore);
226   Release(thr, pc, addr);
227 }
228
229 void INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {
230   SCOPED_ANNOTATION(AnnotateHappensAfter);
231   Acquire(thr, pc, addr);
232 }
233
234 void INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {
235   SCOPED_ANNOTATION(AnnotateCondVarSignal);
236 }
237
238 void INTERFACE_ATTRIBUTE AnnotateCondVarSignalAll(char *f, int l, uptr cv) {
239   SCOPED_ANNOTATION(AnnotateCondVarSignalAll);
240 }
241
242 void INTERFACE_ATTRIBUTE AnnotateMutexIsNotPHB(char *f, int l, uptr mu) {
243   SCOPED_ANNOTATION(AnnotateMutexIsNotPHB);
244 }
245
246 void INTERFACE_ATTRIBUTE AnnotateCondVarWait(char *f, int l, uptr cv,
247                                              uptr lock) {
248   SCOPED_ANNOTATION(AnnotateCondVarWait);
249 }
250
251 void INTERFACE_ATTRIBUTE AnnotateRWLockCreate(char *f, int l, uptr m) {
252   SCOPED_ANNOTATION(AnnotateRWLockCreate);
253   MutexCreate(thr, pc, m, true, true, false);
254 }
255
256 void INTERFACE_ATTRIBUTE AnnotateRWLockCreateStatic(char *f, int l, uptr m) {
257   SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);
258   MutexCreate(thr, pc, m, true, true, true);
259 }
260
261 void INTERFACE_ATTRIBUTE AnnotateRWLockDestroy(char *f, int l, uptr m) {
262   SCOPED_ANNOTATION(AnnotateRWLockDestroy);
263   MutexDestroy(thr, pc, m);
264 }
265
266 void INTERFACE_ATTRIBUTE AnnotateRWLockAcquired(char *f, int l, uptr m,
267                                                 uptr is_w) {
268   SCOPED_ANNOTATION(AnnotateRWLockAcquired);
269   if (is_w)
270     MutexLock(thr, pc, m);
271   else
272     MutexReadLock(thr, pc, m);
273 }
274
275 void INTERFACE_ATTRIBUTE AnnotateRWLockReleased(char *f, int l, uptr m,
276                                                 uptr is_w) {
277   SCOPED_ANNOTATION(AnnotateRWLockReleased);
278   if (is_w)
279     MutexUnlock(thr, pc, m);
280   else
281     MutexReadUnlock(thr, pc, m);
282 }
283
284 void INTERFACE_ATTRIBUTE AnnotateTraceMemory(char *f, int l, uptr mem) {
285   SCOPED_ANNOTATION(AnnotateTraceMemory);
286 }
287
288 void INTERFACE_ATTRIBUTE AnnotateFlushState(char *f, int l) {
289   SCOPED_ANNOTATION(AnnotateFlushState);
290 }
291
292 void INTERFACE_ATTRIBUTE AnnotateNewMemory(char *f, int l, uptr mem,
293                                            uptr size) {
294   SCOPED_ANNOTATION(AnnotateNewMemory);
295 }
296
297 void INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {
298   SCOPED_ANNOTATION(AnnotateNoOp);
299 }
300
301 void INTERFACE_ATTRIBUTE AnnotateFlushExpectedRaces(char *f, int l) {
302   SCOPED_ANNOTATION(AnnotateFlushExpectedRaces);
303   Lock lock(&dyn_ann_ctx->mtx);
304   while (dyn_ann_ctx->expect.next != &dyn_ann_ctx->expect) {
305     ExpectRace *race = dyn_ann_ctx->expect.next;
306     if (race->hitcount == 0) {
307       ctx->nmissed_expected++;
308       ReportMissedExpectedRace(race);
309     }
310     race->prev->next = race->next;
311     race->next->prev = race->prev;
312     internal_free(race);
313   }
314 }
315
316 void INTERFACE_ATTRIBUTE AnnotateEnableRaceDetection(
317     char *f, int l, int enable) {
318   SCOPED_ANNOTATION(AnnotateEnableRaceDetection);
319   // FIXME: Reconsider this functionality later. It may be irrelevant.
320 }
321
322 void INTERFACE_ATTRIBUTE AnnotateMutexIsUsedAsCondVar(
323     char *f, int l, uptr mu) {
324   SCOPED_ANNOTATION(AnnotateMutexIsUsedAsCondVar);
325 }
326
327 void INTERFACE_ATTRIBUTE AnnotatePCQGet(
328     char *f, int l, uptr pcq) {
329   SCOPED_ANNOTATION(AnnotatePCQGet);
330 }
331
332 void INTERFACE_ATTRIBUTE AnnotatePCQPut(
333     char *f, int l, uptr pcq) {
334   SCOPED_ANNOTATION(AnnotatePCQPut);
335 }
336
337 void INTERFACE_ATTRIBUTE AnnotatePCQDestroy(
338     char *f, int l, uptr pcq) {
339   SCOPED_ANNOTATION(AnnotatePCQDestroy);
340 }
341
342 void INTERFACE_ATTRIBUTE AnnotatePCQCreate(
343     char *f, int l, uptr pcq) {
344   SCOPED_ANNOTATION(AnnotatePCQCreate);
345 }
346
347 void INTERFACE_ATTRIBUTE AnnotateExpectRace(
348     char *f, int l, uptr mem, char *desc) {
349   SCOPED_ANNOTATION(AnnotateExpectRace);
350   Lock lock(&dyn_ann_ctx->mtx);
351   AddExpectRace(&dyn_ann_ctx->expect,
352                 f, l, mem, 1, desc);
353   DPrintf("Add expected race: %s addr=%zx %s:%d\n", desc, mem, f, l);
354 }
355
356 static void BenignRaceImpl(
357     char *f, int l, uptr mem, uptr size, char *desc) {
358   Lock lock(&dyn_ann_ctx->mtx);
359   AddExpectRace(&dyn_ann_ctx->benign,
360                 f, l, mem, size, desc);
361   DPrintf("Add benign race: %s addr=%zx %s:%d\n", desc, mem, f, l);
362 }
363
364 // FIXME: Turn it off later. WTF is benign race?1?? Go talk to Hans Boehm.
365 void INTERFACE_ATTRIBUTE AnnotateBenignRaceSized(
366     char *f, int l, uptr mem, uptr size, char *desc) {
367   SCOPED_ANNOTATION(AnnotateBenignRaceSized);
368   BenignRaceImpl(f, l, mem, size, desc);
369 }
370
371 void INTERFACE_ATTRIBUTE AnnotateBenignRace(
372     char *f, int l, uptr mem, char *desc) {
373   SCOPED_ANNOTATION(AnnotateBenignRace);
374   BenignRaceImpl(f, l, mem, 1, desc);
375 }
376
377 void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsBegin(char *f, int l) {
378   SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin);
379   ThreadIgnoreBegin(thr, pc);
380 }
381
382 void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsEnd(char *f, int l) {
383   SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd);
384   ThreadIgnoreEnd(thr, pc);
385 }
386
387 void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {
388   SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin);
389   ThreadIgnoreBegin(thr, pc);
390 }
391
392 void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {
393   SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);
394   ThreadIgnoreEnd(thr, pc);
395 }
396
397 void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncBegin(char *f, int l) {
398   SCOPED_ANNOTATION(AnnotateIgnoreSyncBegin);
399   ThreadIgnoreSyncBegin(thr, pc);
400 }
401
402 void INTERFACE_ATTRIBUTE AnnotateIgnoreSyncEnd(char *f, int l) {
403   SCOPED_ANNOTATION(AnnotateIgnoreSyncEnd);
404   ThreadIgnoreSyncEnd(thr, pc);
405 }
406
407 void INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(
408     char *f, int l, uptr addr, uptr size) {
409   SCOPED_ANNOTATION(AnnotatePublishMemoryRange);
410 }
411
412 void INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(
413     char *f, int l, uptr addr, uptr size) {
414   SCOPED_ANNOTATION(AnnotateUnpublishMemoryRange);
415 }
416
417 void INTERFACE_ATTRIBUTE AnnotateThreadName(
418     char *f, int l, char *name) {
419   SCOPED_ANNOTATION(AnnotateThreadName);
420   ThreadSetName(thr, name);
421 }
422
423 // We deliberately omit the implementation of WTFAnnotateHappensBefore() and
424 // WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate
425 // atomic operations, which should be handled by ThreadSanitizer correctly.
426 void INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {
427   SCOPED_ANNOTATION(AnnotateHappensBefore);
428 }
429
430 void INTERFACE_ATTRIBUTE WTFAnnotateHappensAfter(char *f, int l, uptr addr) {
431   SCOPED_ANNOTATION(AnnotateHappensAfter);
432 }
433
434 void INTERFACE_ATTRIBUTE WTFAnnotateBenignRaceSized(
435     char *f, int l, uptr mem, uptr sz, char *desc) {
436   SCOPED_ANNOTATION(AnnotateBenignRaceSized);
437   BenignRaceImpl(f, l, mem, sz, desc);
438 }
439
440 int INTERFACE_ATTRIBUTE RunningOnValgrind() {
441   return flags()->running_on_valgrind;
442 }
443
444 double __attribute__((weak)) INTERFACE_ATTRIBUTE ValgrindSlowdown(void) {
445   return 10.0;
446 }
447
448 const char INTERFACE_ATTRIBUTE* ThreadSanitizerQuery(const char *query) {
449   if (internal_strcmp(query, "pure_happens_before") == 0)
450     return "1";
451   else
452     return "0";
453 }
454
455 void INTERFACE_ATTRIBUTE
456 AnnotateMemoryIsInitialized(char *f, int l, uptr mem, uptr sz) {}
457 void INTERFACE_ATTRIBUTE
458 AnnotateMemoryIsUninitialized(char *f, int l, uptr mem, uptr sz) {}
459 }  // extern "C"