[llvm-commits] [compiler-rt] r163006 - in /compiler-rt/trunk/lib/tsan: output_tests/race_on_heap.cc output_tests/sleep_sync.cc output_tests/sleep_sync2.cc rtl/tsan_interceptors.cc rtl/tsan_mman.cc rtl/tsan_report.cc rtl/tsan_report.h rtl/tsan_rtl.cc rtl/tsan_rtl.h rtl/tsan_rtl_mutex.cc rtl/tsan_rtl_report.cc rtl/tsan_stat.h

Dmitry Vyukov dvyukov at google.com
Fri Aug 31 10:27:50 PDT 2012


Author: dvyukov
Date: Fri Aug 31 12:27:49 2012
New Revision: 163006

URL: http://llvm.org/viewvc/llvm-project?rev=163006&view=rev
Log:
tsan: add "as if synchronized via sleep" feature

Added:
    compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc
    compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc
Modified:
    compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h

Modified: compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc (original)
+++ compiler-rt/trunk/lib/tsan/output_tests/race_on_heap.cc Fri Aug 31 12:27:49 2012
@@ -37,8 +37,9 @@
 // CHECK: WARNING: ThreadSanitizer: data race
 // ...
 // CHECK:   Location is heap block of size 99 at [[ADDR]] allocated by thread 1:
-// CHECK:     #0 alloc
-// CHECK:     #1 AllocThread
+// CHCEKL     #0 malloc
+// CHECK:     #1 alloc
+// CHECK:     #2 AllocThread
 // ...
 // CHECK:   Thread 1 (finished) created at:
 // CHECK:     #0 pthread_create

Added: compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc?rev=163006&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc (added)
+++ compiler-rt/trunk/lib/tsan/output_tests/sleep_sync.cc Fri Aug 31 12:27:49 2012
@@ -0,0 +1,30 @@
+#include <pthread.h>
+#include <unistd.h>
+
+int X = 0;
+
+void *Thread(void *p) {
+  X = 42;
+  return 0;
+}
+
+void MySleep() {
+  usleep(100*1000);
+}
+
+int main() {
+  pthread_t t;
+  pthread_create(&t, 0, Thread, 0);
+  MySleep();  // Assume the thread has done the write.
+  X = 43;
+  pthread_join(t, 0);
+  return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// ...
+// CHECK:   As if synchronized via sleep:
+// CHECK-NEXT:     #0 usleep
+// CHECK-NEXT:     #1 MySleep
+// CHECK-NEXT:     #2 main
+

Added: compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc?rev=163006&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc (added)
+++ compiler-rt/trunk/lib/tsan/output_tests/sleep_sync2.cc Fri Aug 31 12:27:49 2012
@@ -0,0 +1,21 @@
+#include <pthread.h>
+#include <unistd.h>
+
+int X = 0;
+
+void *Thread(void *p) {
+  X = 42;
+  return 0;
+}
+
+int main() {
+  pthread_t t;
+  usleep(100*1000);
+  pthread_create(&t, 0, Thread, 0);
+  X = 43;
+  pthread_join(t, 0);
+  return 0;
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK-NOT: As if synchronized via sleep

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Fri Aug 31 12:27:49 2012
@@ -51,7 +51,6 @@
 extern "C" void _exit(int status);
 extern "C" int __cxa_atexit(void (*func)(void *arg), void *arg, void *dso);
 extern "C" int *__errno_location();
-extern "C" int usleep(unsigned usec);
 const int PTHREAD_MUTEX_RECURSIVE = 1;
 const int PTHREAD_MUTEX_RECURSIVE_NP = 1;
 const int kPthreadAttrSize = 56;
@@ -213,6 +212,27 @@
   __tsan_free_hook(ptr);
 }
 
+TSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) {
+  SCOPED_TSAN_INTERCEPTOR(sleep, sec);
+  unsigned res = sleep(sec);
+  AfterSleep(thr, pc);
+  return res;
+}
+
+TSAN_INTERCEPTOR(int, usleep, long_t usec) {
+  SCOPED_TSAN_INTERCEPTOR(usleep, usec);
+  int res = usleep(usec);
+  AfterSleep(thr, pc);
+  return res;
+}
+
+TSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) {
+  SCOPED_TSAN_INTERCEPTOR(nanosleep, req, rem);
+  int res = nanosleep(req, rem);
+  AfterSleep(thr, pc);
+  return res;
+}
+
 class AtExitContext {
  public:
   AtExitContext()
@@ -269,7 +289,7 @@
   {
     ScopedInRtl in_rtl;
     DestroyAndFree(atexit_ctx);
-    usleep(flags()->atexit_sleep_ms * 1000);
+    REAL(usleep)(flags()->atexit_sleep_ms * 1000);
   }
   int status = Finalize(cur_thread());
   if (status)
@@ -1572,6 +1592,9 @@
   TSAN_INTERCEPT(raise);
   TSAN_INTERCEPT(kill);
   TSAN_INTERCEPT(pthread_kill);
+  TSAN_INTERCEPT(sleep);
+  TSAN_INTERCEPT(usleep);
+  TSAN_INTERCEPT(nanosleep);
 
   atexit_ctx = new(internal_alloc(MBlockAtExit, sizeof(AtExitContext)))
       AtExitContext();

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Fri Aug 31 12:27:49 2012
@@ -12,7 +12,6 @@
 //===----------------------------------------------------------------------===//
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
 #include "tsan_mman.h"
 #include "tsan_rtl.h"
 #include "tsan_report.h"
@@ -51,10 +50,7 @@
   MBlock *b = (MBlock*)allocator()->GetMetaData(p);
   b->size = sz;
   b->alloc_tid = thr->unique_id;
-  b->alloc_stack_id = 0;
-  if (thr->shadow_stack_pos)  // May happen during bootstrap.
-    b->alloc_stack_id = StackDepotPut(thr->shadow_stack,
-        thr->shadow_stack_pos - thr->shadow_stack);
+  b->alloc_stack_id = CurrentStackId(thr, pc);
   if (CTX() && CTX()->initialized) {
     MemoryRangeImitateWrite(thr, pc, (uptr)p, sz);
   }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.cc Fri Aug 31 12:27:49 2012
@@ -21,7 +21,8 @@
     , mops(MBlockReportMop)
     , locs(MBlockReportLoc)
     , mutexes(MBlockReportMutex)
-    , threads(MBlockReportThread) {
+    , threads(MBlockReportThread)
+    , sleep() {
 }
 
 ReportDesc::~ReportDesc() {
@@ -110,6 +111,11 @@
   PrintStack(rt->stack);
 }
 
+static void PrintSleep(const ReportStack *s) {
+  TsanPrintf("  As if synchronized via sleep:\n");
+  PrintStack(s);
+}
+
 void PrintReport(const ReportDesc *rep) {
   TsanPrintf("==================\n");
   PrintHeader(rep->typ);
@@ -123,6 +129,9 @@
   for (uptr i = 0; i < rep->mops.Size(); i++)
     PrintMop(rep->mops[i], i == 0);
 
+  if (rep->sleep)
+    PrintSleep(rep->sleep);
+
   for (uptr i = 0; i < rep->locs.Size(); i++)
     PrintLocation(rep->locs[i]);
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_report.h?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_report.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_report.h Fri Aug 31 12:27:49 2012
@@ -85,6 +85,7 @@
   Vector<ReportLocation*> locs;
   Vector<ReportMutex*> mutexes;
   Vector<ReportThread*> threads;
+  ReportStack *sleep;
 
   ReportDesc();
   ~ReportDesc();

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Fri Aug 31 12:27:49 2012
@@ -15,6 +15,7 @@
 #include "sanitizer_common/sanitizer_atomic.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
 #include "tsan_defs.h"
 #include "tsan_platform.h"
@@ -223,6 +224,20 @@
   return failed ? flags()->exitcode : 0;
 }
 
+u32 CurrentStackId(ThreadState *thr, uptr pc) {
+  if (thr->shadow_stack_pos == 0)  // May happen during bootstrap.
+    return 0;
+  if (pc) {
+    thr->shadow_stack_pos[0] = pc;
+    thr->shadow_stack_pos++;
+  }
+  u32 id = StackDepotPut(thr->shadow_stack,
+                         thr->shadow_stack_pos - thr->shadow_stack);
+  if (pc)
+    thr->shadow_stack_pos--;
+  return id;
+}
+
 void TraceSwitch(ThreadState *thr) {
   thr->nomalloc++;
   ScopedInRtl in_rtl;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Fri Aug 31 12:27:49 2012
@@ -286,6 +286,11 @@
   bool in_signal_handler;
   SignalContext *signal_ctx;
 
+#ifndef TSAN_GO
+  u32 last_sleep_stack_id;
+  ThreadClock last_sleep_clock;
+#endif
+
   // Set in regions of runtime that must be signal-safe and fork-safe.
   // If set, malloc must not be called.
   int nomalloc;
@@ -405,6 +410,7 @@
   void AddThread(const ThreadContext *tctx);
   void AddMutex(const SyncVar *s);
   void AddLocation(uptr addr, uptr size);
+  void AddSleep(u32 stack_id);
 
   const ReportDesc *GetReport() const;
 
@@ -446,6 +452,8 @@
 # define DPrintf2(...)
 #endif
 
+u32 CurrentStackId(ThreadState *thr, uptr pc);
+
 void Initialize(ThreadState *thr);
 int Finalize(ThreadState *thr);
 
@@ -489,6 +497,7 @@
 void Acquire(ThreadState *thr, uptr pc, uptr addr);
 void Release(ThreadState *thr, uptr pc, uptr addr);
 void ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
+void AfterSleep(ThreadState *thr, uptr pc);
 
 // The hacky call uses custom calling convention and an assembly thunk.
 // It is considerably faster that a normal call for the caller

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Aug 31 12:27:49 2012
@@ -230,4 +230,21 @@
   s->mtx.Unlock();
 }
 
+#ifndef TSAN_GO
+void AfterSleep(ThreadState *thr, uptr pc) {
+  Context *ctx = CTX();
+  thr->last_sleep_stack_id = CurrentStackId(thr, pc);
+  Lock l(&ctx->thread_mtx);
+  for (unsigned i = 0; i < kMaxTid; i++) {
+    ThreadContext *tctx = ctx->threads[i];
+    if (tctx == 0)
+      continue;
+    if (tctx->status == ThreadStatusRunning)
+      thr->last_sleep_clock.set(i, tctx->thr->fast_state.epoch());
+    else
+      thr->last_sleep_clock.set(i, tctx->epoch1);
+  }
+}
+#endif
+
 }  // namespace __tsan

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Fri Aug 31 12:27:49 2012
@@ -230,6 +230,16 @@
   }
 }
 
+void ScopedReport::AddSleep(u32 stack_id) {
+  uptr ssz = 0;
+  const uptr *stack = StackDepotGet(stack_id, &ssz);
+  if (stack) {
+    StackTrace trace;
+    trace.Init(stack, ssz);
+    rep_->sleep = SymbolizeStack(trace);
+  }
+}
+
 const ReportDesc *ScopedReport::GetReport() const {
   return rep_;
 }
@@ -411,6 +421,14 @@
 
   rep.AddLocation(addr_min, addr_max - addr_min);
 
+#ifndef TSAN_GO
+  {  // NOLINT
+    Shadow s(thr->racy_state[1]);
+    if (s.epoch() <= thr->last_sleep_clock.get(s.tid()))
+      rep.AddSleep(thr->last_sleep_stack_id);
+  }
+#endif
+
   if (!OutputReport(rep, rep.GetReport()->mops[0]->stack))
     return;
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=163006&r1=163005&r2=163006&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Fri Aug 31 12:27:49 2012
@@ -199,6 +199,9 @@
   StatInt_raise,
   StatInt_kill,
   StatInt_pthread_kill,
+  StatInt_sleep,
+  StatInt_usleep,
+  StatInt_nanosleep,
 
   // Dynamic annotations.
   StatAnnotation,





More information about the llvm-commits mailing list