Home | History | Annotate | Download | only in rtl
      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       , in_rtl_(thr->in_rtl) {
     38     CHECK_EQ(thr_->in_rtl, 0);
     39     FuncEntry(thr_, pc);
     40     thr_->in_rtl++;
     41     DPrintf("#%d: annotation %s() %s:%d\n", thr_->tid, aname, f, l);
     42   }
     43 
     44   ~ScopedAnnotation() {
     45     thr_->in_rtl--;
     46     CHECK_EQ(in_rtl_, thr_->in_rtl);
     47     FuncExit(thr_);
     48   }
     49  private:
     50   ThreadState *const thr_;
     51   const int in_rtl_;
     52 };
     53 
     54 #define SCOPED_ANNOTATION(typ) \
     55     if (!flags()->enable_annotations) \
     56       return; \
     57     ThreadState *thr = cur_thread(); \
     58     const uptr pc = (uptr)__builtin_return_address(0); \
     59     StatInc(thr, StatAnnotation); \
     60     StatInc(thr, Stat##typ); \
     61     ScopedAnnotation sa(thr, __FUNCTION__, f, l, \
     62         (uptr)__builtin_return_address(0)); \
     63     (void)pc; \
     64 /**/
     65 
     66 static const int kMaxDescLen = 128;
     67 
     68 struct ExpectRace {
     69   ExpectRace *next;
     70   ExpectRace *prev;
     71   int hitcount;
     72   int addcount;
     73   uptr addr;
     74   uptr size;
     75   char *file;
     76   int line;
     77   char desc[kMaxDescLen];
     78 };
     79 
     80 struct DynamicAnnContext {
     81   Mutex mtx;
     82   ExpectRace expect;
     83   ExpectRace benign;
     84 
     85   DynamicAnnContext()
     86     : mtx(MutexTypeAnnotations, StatMtxAnnotations) {
     87   }
     88 };
     89 
     90 static DynamicAnnContext *dyn_ann_ctx;
     91 static char dyn_ann_ctx_placeholder[sizeof(DynamicAnnContext)] ALIGNED(64);
     92 
     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) {
     98       race->addcount++;
     99       return;
    100     }
    101   }
    102   race = (ExpectRace*)internal_alloc(MBlockExpectRace, sizeof(ExpectRace));
    103   race->addr = addr;
    104   race->size = size;
    105   race->file = f;
    106   race->line = l;
    107   race->desc[0] = 0;
    108   race->hitcount = 0;
    109   race->addcount = 1;
    110   if (desc) {
    111     int i = 0;
    112     for (; i < kMaxDescLen - 1 && desc[i]; i++)
    113       race->desc[i] = desc[i];
    114     race->desc[i] = 0;
    115   }
    116   race->prev = list;
    117   race->next = list->next;
    118   race->next->prev = race;
    119   list->next = race;
    120 }
    121 
    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)
    127       return race;
    128   }
    129   return 0;
    130 }
    131 
    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);
    136   if (race == 0)
    137     return false;
    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);
    140   race->hitcount++;
    141   return true;
    142 }
    143 
    144 static void InitList(ExpectRace *list) {
    145   list->next = list;
    146   list->prev = list;
    147 }
    148 
    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);
    153 }
    154 
    155 bool IsExpectedReport(uptr addr, uptr size) {
    156   Lock lock(&dyn_ann_ctx->mtx);
    157   if (CheckContains(&dyn_ann_ctx->expect, addr, size))
    158     return true;
    159   if (CheckContains(&dyn_ann_ctx->benign, addr, size))
    160     return true;
    161   return false;
    162 }
    163 
    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) {
    168     (*unique_count)++;
    169     if (race->*counter == 0)
    170       continue;
    171     (*hit_count) += race->*counter;
    172     uptr i = 0;
    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;
    179         break;
    180       }
    181     }
    182     if (i == matched->Size())
    183       matched->PushBack(*race);
    184   }
    185 }
    186 
    187 void PrintMatchedBenignRaces() {
    188   Lock lock(&dyn_ann_ctx->mtx);
    189   int unique_count = 0;
    190   int hit_count = 0;
    191   int add_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);
    205     }
    206   }
    207   if (hit_matched.Size()) {
    208     Printf("ThreadSanitizer: Annotated %d \"benign\" races, %d unique"
    209            " (pid=%d):\n",
    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);
    215     }
    216   }
    217 }
    218 
    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");
    225 }
    226 }  // namespace __tsan
    227 
    228 using namespace __tsan;  // NOLINT
    229 
    230 extern "C" {
    231 void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) {
    232   SCOPED_ANNOTATION(AnnotateHappensBefore);
    233   Release(cur_thread(), pc, addr);
    234 }
    235 
    236 void INTERFACE_ATTRIBUTE AnnotateHappensAfter(char *f, int l, uptr addr) {
    237   SCOPED_ANNOTATION(AnnotateHappensAfter);
    238   Acquire(cur_thread(), pc, addr);
    239 }
    240 
    241 void INTERFACE_ATTRIBUTE AnnotateCondVarSignal(char *f, int l, uptr cv) {
    242   SCOPED_ANNOTATION(AnnotateCondVarSignal);
    243 }
    244 
    245 void INTERFACE_ATTRIBUTE AnnotateCondVarSignalAll(char *f, int l, uptr cv) {
    246   SCOPED_ANNOTATION(AnnotateCondVarSignalAll);
    247 }
    248 
    249 void INTERFACE_ATTRIBUTE AnnotateMutexIsNotPHB(char *f, int l, uptr mu) {
    250   SCOPED_ANNOTATION(AnnotateMutexIsNotPHB);
    251 }
    252 
    253 void INTERFACE_ATTRIBUTE AnnotateCondVarWait(char *f, int l, uptr cv,
    254                                              uptr lock) {
    255   SCOPED_ANNOTATION(AnnotateCondVarWait);
    256 }
    257 
    258 void INTERFACE_ATTRIBUTE AnnotateRWLockCreate(char *f, int l, uptr m) {
    259   SCOPED_ANNOTATION(AnnotateRWLockCreate);
    260   MutexCreate(thr, pc, m, true, true, false);
    261 }
    262 
    263 void INTERFACE_ATTRIBUTE AnnotateRWLockCreateStatic(char *f, int l, uptr m) {
    264   SCOPED_ANNOTATION(AnnotateRWLockCreateStatic);
    265   MutexCreate(thr, pc, m, true, true, true);
    266 }
    267 
    268 void INTERFACE_ATTRIBUTE AnnotateRWLockDestroy(char *f, int l, uptr m) {
    269   SCOPED_ANNOTATION(AnnotateRWLockDestroy);
    270   MutexDestroy(thr, pc, m);
    271 }
    272 
    273 void INTERFACE_ATTRIBUTE AnnotateRWLockAcquired(char *f, int l, uptr m,
    274                                                 uptr is_w) {
    275   SCOPED_ANNOTATION(AnnotateRWLockAcquired);
    276   if (is_w)
    277     MutexLock(thr, pc, m);
    278   else
    279     MutexReadLock(thr, pc, m);
    280 }
    281 
    282 void INTERFACE_ATTRIBUTE AnnotateRWLockReleased(char *f, int l, uptr m,
    283                                                 uptr is_w) {
    284   SCOPED_ANNOTATION(AnnotateRWLockReleased);
    285   if (is_w)
    286     MutexUnlock(thr, pc, m);
    287   else
    288     MutexReadUnlock(thr, pc, m);
    289 }
    290 
    291 void INTERFACE_ATTRIBUTE AnnotateTraceMemory(char *f, int l, uptr mem) {
    292   SCOPED_ANNOTATION(AnnotateTraceMemory);
    293 }
    294 
    295 void INTERFACE_ATTRIBUTE AnnotateFlushState(char *f, int l) {
    296   SCOPED_ANNOTATION(AnnotateFlushState);
    297 }
    298 
    299 void INTERFACE_ATTRIBUTE AnnotateNewMemory(char *f, int l, uptr mem,
    300                                            uptr size) {
    301   SCOPED_ANNOTATION(AnnotateNewMemory);
    302 }
    303 
    304 void INTERFACE_ATTRIBUTE AnnotateNoOp(char *f, int l, uptr mem) {
    305   SCOPED_ANNOTATION(AnnotateNoOp);
    306 }
    307 
    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);
    316     }
    317     race->prev->next = race->next;
    318     race->next->prev = race->prev;
    319     internal_free(race);
    320   }
    321 }
    322 
    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.
    327 }
    328 
    329 void INTERFACE_ATTRIBUTE AnnotateMutexIsUsedAsCondVar(
    330     char *f, int l, uptr mu) {
    331   SCOPED_ANNOTATION(AnnotateMutexIsUsedAsCondVar);
    332 }
    333 
    334 void INTERFACE_ATTRIBUTE AnnotatePCQGet(
    335     char *f, int l, uptr pcq) {
    336   SCOPED_ANNOTATION(AnnotatePCQGet);
    337 }
    338 
    339 void INTERFACE_ATTRIBUTE AnnotatePCQPut(
    340     char *f, int l, uptr pcq) {
    341   SCOPED_ANNOTATION(AnnotatePCQPut);
    342 }
    343 
    344 void INTERFACE_ATTRIBUTE AnnotatePCQDestroy(
    345     char *f, int l, uptr pcq) {
    346   SCOPED_ANNOTATION(AnnotatePCQDestroy);
    347 }
    348 
    349 void INTERFACE_ATTRIBUTE AnnotatePCQCreate(
    350     char *f, int l, uptr pcq) {
    351   SCOPED_ANNOTATION(AnnotatePCQCreate);
    352 }
    353 
    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,
    359                 f, l, mem, 1, desc);
    360   DPrintf("Add expected race: %s addr=%zx %s:%d\n", desc, mem, f, l);
    361 }
    362 
    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);
    369 }
    370 
    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);
    376 }
    377 
    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);
    382 }
    383 
    384 void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsBegin(char *f, int l) {
    385   SCOPED_ANNOTATION(AnnotateIgnoreReadsBegin);
    386   IgnoreCtl(cur_thread(), false, true);
    387 }
    388 
    389 void INTERFACE_ATTRIBUTE AnnotateIgnoreReadsEnd(char *f, int l) {
    390   SCOPED_ANNOTATION(AnnotateIgnoreReadsEnd);
    391   IgnoreCtl(cur_thread(), false, false);
    392 }
    393 
    394 void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesBegin(char *f, int l) {
    395   SCOPED_ANNOTATION(AnnotateIgnoreWritesBegin);
    396   IgnoreCtl(cur_thread(), true, true);
    397 }
    398 
    399 void INTERFACE_ATTRIBUTE AnnotateIgnoreWritesEnd(char *f, int l) {
    400   SCOPED_ANNOTATION(AnnotateIgnoreWritesEnd);
    401   IgnoreCtl(thr, true, false);
    402 }
    403 
    404 void INTERFACE_ATTRIBUTE AnnotatePublishMemoryRange(
    405     char *f, int l, uptr addr, uptr size) {
    406   SCOPED_ANNOTATION(AnnotatePublishMemoryRange);
    407 }
    408 
    409 void INTERFACE_ATTRIBUTE AnnotateUnpublishMemoryRange(
    410     char *f, int l, uptr addr, uptr size) {
    411   SCOPED_ANNOTATION(AnnotateUnpublishMemoryRange);
    412 }
    413 
    414 void INTERFACE_ATTRIBUTE AnnotateThreadName(
    415     char *f, int l, char *name) {
    416   SCOPED_ANNOTATION(AnnotateThreadName);
    417   ThreadSetName(thr, name);
    418 }
    419 
    420 // We deliberately omit the implementation of WTFAnnotateHappensBefore() and
    421 // WTFAnnotateHappensAfter(). Those are being used by Webkit to annotate
    422 // atomic operations, which should be handled by ThreadSanitizer correctly.
    423 void INTERFACE_ATTRIBUTE WTFAnnotateHappensBefore(char *f, int l, uptr addr) {
    424   SCOPED_ANNOTATION(AnnotateHappensBefore);
    425 }
    426 
    427 void INTERFACE_ATTRIBUTE WTFAnnotateHappensAfter(char *f, int l, uptr addr) {
    428   SCOPED_ANNOTATION(AnnotateHappensAfter);
    429 }
    430 
    431 void INTERFACE_ATTRIBUTE WTFAnnotateBenignRaceSized(
    432     char *f, int l, uptr mem, uptr sz, char *desc) {
    433   SCOPED_ANNOTATION(AnnotateBenignRaceSized);
    434   BenignRaceImpl(f, l, mem, 1, desc);
    435 }
    436 
    437 int INTERFACE_ATTRIBUTE RunningOnValgrind() {
    438   return flags()->running_on_valgrind;
    439 }
    440 
    441 double __attribute__((weak)) INTERFACE_ATTRIBUTE ValgrindSlowdown(void) {
    442   return 10.0;
    443 }
    444 
    445 const char INTERFACE_ATTRIBUTE* ThreadSanitizerQuery(const char *query) {
    446   if (internal_strcmp(query, "pure_happens_before") == 0)
    447     return "1";
    448   else
    449     return "0";
    450 }
    451 }  // extern "C"
    452