[llvm-commits] [compiler-rt] r158988 - in /compiler-rt/trunk/lib/tsan/rtl: tsan_defs.h tsan_mman.cc tsan_rtl.cc tsan_rtl.h tsan_sync.cc tsan_sync.h tsan_trace.h

Dmitry Vyukov dvyukov at google.com
Fri Jun 22 04:08:56 PDT 2012


Author: dvyukov
Date: Fri Jun 22 06:08:55 2012
New Revision: 158988

URL: http://llvm.org/viewvc/llvm-project?rev=158988&view=rev
Log:
tsan: do not call malloc/free in memory access handling routine.
This improves signal-/fork-safety of instrumented programs.


Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
    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_sync.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h?rev=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h Fri Jun 22 06:08:55 2012
@@ -29,6 +29,7 @@
 const unsigned kMaxTid = 1 << kTidBits;
 const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
 const int kClkBits = 43;
+const int kShadowStackSize = 1024;
 
 #ifdef TSAN_SHADOW_COUNT
 # if TSAN_SHADOW_COUNT == 2 \

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=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Fri Jun 22 06:08:55 2012
@@ -104,12 +104,20 @@
 void *internal_alloc(MBlockType typ, uptr sz) {
   ThreadState *thr = cur_thread();
   CHECK_GT(thr->in_rtl, 0);
+  if (thr->nomalloc) {
+    thr->nomalloc = 0;  // CHECK calls internal_malloc().
+    CHECK(0);
+  }
   return InternalAlloc(sz);
 }
 
 void internal_free(void *p) {
   ThreadState *thr = cur_thread();
   CHECK_GT(thr->in_rtl, 0);
+  if (thr->nomalloc) {
+    thr->nomalloc = 0;  // CHECK calls internal_malloc().
+    CHECK(0);
+  }
   InternalFree(p);
 }
 

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=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Fri Jun 22 06:08:55 2012
@@ -219,12 +219,14 @@
 }
 
 static void TraceSwitch(ThreadState *thr) {
+  thr->nomalloc++;
   ScopedInRtl in_rtl;
   Lock l(&thr->trace.mtx);
   unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % kTraceParts;
   TraceHeader *hdr = &thr->trace.headers[trace];
   hdr->epoch0 = thr->fast_state.epoch();
   hdr->stack0.ObtainCurrent(thr, 0);
+  thr->nomalloc--;
 }
 
 extern "C" void __tsan_trace_switch() {

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=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Fri Jun 22 06:08:55 2012
@@ -204,7 +204,6 @@
 const u64 kShadowFreed = 0xfffffffffffffff8ull;
 
 const int kSigCount = 128;
-const int kShadowStackSize = 1024;
 
 struct my_siginfo_t {
   int opaque[128];
@@ -255,6 +254,9 @@
   int int_signal_send;
   int pending_signal_count;
   SignalDesc pending_signals[kSigCount];
+  // Set in regions of runtime that must be signal-safe and fork-safe.
+  // If set, malloc must not be called.
+  int nomalloc;
 
   explicit ThreadState(Context *ctx, int tid, u64 epoch,
                        uptr stk_addr, uptr stk_size,

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc?rev=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc Fri Jun 22 06:08:55 2012
@@ -133,7 +133,16 @@
 
 StackTrace::StackTrace()
     : n_()
-    , s_() {
+    , s_()
+    , c_() {
+}
+
+StackTrace::StackTrace(uptr *buf, uptr cnt)
+    : n_()
+    , s_(buf)
+    , c_(cnt) {
+  CHECK_NE(buf, 0);
+  CHECK_NE(cnt, 0);
 }
 
 StackTrace::~StackTrace() {
@@ -141,21 +150,26 @@
 }
 
 void StackTrace::Reset() {
-  if (s_) {
+  if (s_ && !c_) {
     CHECK_NE(n_, 0);
     internal_free(s_);
     s_ = 0;
-    n_ = 0;
   }
+  n_ = 0;
 }
 
 void StackTrace::Init(const uptr *pcs, uptr cnt) {
   Reset();
   if (cnt == 0)
     return;
+  if (c_) {
+    CHECK_NE(s_, 0);
+    CHECK_LE(cnt, c_);
+  } else {
+    s_ = (uptr*)internal_alloc(MBlockStackTrace, cnt * sizeof(s_[0]));
+  }
   n_ = cnt;
-  s_ = (uptr*)internal_alloc(MBlockStackTrace, cnt * sizeof(s_[0]));
-  REAL(memcpy)(s_, pcs, cnt * sizeof(s_[0]));
+  internal_memcpy(s_, pcs, cnt * sizeof(s_[0]));
 }
 
 void StackTrace::ObtainCurrent(ThreadState *thr, uptr toppc) {
@@ -163,7 +177,13 @@
   n_ = thr->shadow_stack_pos - &thr->shadow_stack[0];
   if (n_ + !!toppc == 0)
     return;
-  s_ = (uptr*)internal_alloc(MBlockStackTrace, (n_ + !!toppc) * sizeof(s_[0]));
+  if (c_) {
+    CHECK_NE(s_, 0);
+    CHECK_LE(n_ + !!toppc, c_);
+  } else {
+    s_ = (uptr*)internal_alloc(MBlockStackTrace,
+                               (n_ + !!toppc) * sizeof(s_[0]));
+  }
   for (uptr i = 0; i < n_; i++)
     s_[i] = thr->shadow_stack[i];
   if (toppc) {

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h?rev=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h Fri Jun 22 06:08:55 2012
@@ -25,6 +25,9 @@
 class StackTrace {
  public:
   StackTrace();
+  // Initialized the object in "static mode",
+  // in this mode it never calls malloc/free but uses the provided buffer.
+  StackTrace(uptr *buf, uptr cnt);
   ~StackTrace();
   void Reset();
 
@@ -39,6 +42,7 @@
  private:
   uptr n_;
   uptr *s_;
+  const uptr c_;
 
   StackTrace(const StackTrace&);
   void operator = (const StackTrace&);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h?rev=158988&r1=158987&r2=158988&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h Fri Jun 22 06:08:55 2012
@@ -41,7 +41,13 @@
 
 struct TraceHeader {
   StackTrace stack0;  // Start stack for the trace.
-  u64   epoch0;       // Start epoch for the trace.
+  u64        epoch0;  // Start epoch for the trace.
+  uptr       stack0buf[kShadowStackSize];
+
+  TraceHeader()
+      : stack0(stack0buf, kShadowStackSize)
+      , epoch0() {
+  }
 };
 
 struct Trace {





More information about the llvm-commits mailing list