[compiler-rt] r207114 - tsan: stop background thread when sandbox is enabled

Dmitry Vyukov dvyukov at google.com
Thu Apr 24 06:09:18 PDT 2014


Author: dvyukov
Date: Thu Apr 24 08:09:17 2014
New Revision: 207114

URL: http://llvm.org/viewvc/llvm-project?rev=207114&view=rev
Log:
tsan: stop background thread when sandbox is enabled
Fixes https://code.google.com/p/thread-sanitizer/issues/detail?id=56


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/tsan/go/tsan_go.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Thu Apr 24 08:09:17 2014
@@ -263,6 +263,11 @@ void DecreaseTotalMmap(uptr size) {
   atomic_fetch_sub(&g_total_mmaped, size, memory_order_relaxed);
 }
 
+static void (*sandboxing_callback)();
+void SetSandboxingCallback(void (*f)()) {
+  sandboxing_callback = f;
+}
+
 }  // namespace __sanitizer
 
 using namespace __sanitizer;  // NOLINT
@@ -298,6 +303,8 @@ void __sanitizer_set_report_path(const c
 void NOINLINE __sanitizer_sandbox_on_notify(void *reserved) {
   (void)reserved;
   PrepareForSandboxing();
+  if (sandboxing_callback)
+    sandboxing_callback();
 }
 
 void __sanitizer_report_error_summary(const char *error_summary) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu Apr 24 08:09:17 2014
@@ -184,6 +184,7 @@ bool StackSizeIsUnlimited();
 void SetStackSizeLimitInBytes(uptr limit);
 void AdjustStackSize(void *attr);
 void PrepareForSandboxing();
+void SetSandboxingCallback(void (*f)());
 
 void InitTlsSize();
 uptr GetTlsSize();

Modified: compiler-rt/trunk/lib/tsan/go/tsan_go.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/tsan_go.cc?rev=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/tsan_go.cc (original)
+++ compiler-rt/trunk/lib/tsan/go/tsan_go.cc Thu Apr 24 08:09:17 2014
@@ -28,7 +28,11 @@ bool IsExpectedReport(uptr addr, uptr si
   return false;
 }
 
-void internal_start_thread(void(*func)(void*), void *arg) {
+void *internal_start_thread(void(*func)(void*), void *arg) {
+  return 0;
+}
+
+void internal_join_thread(void *th) {
 }
 
 ReportLocation *SymbolizeData(uptr addr) {

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=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Thu Apr 24 08:09:17 2014
@@ -2473,15 +2473,19 @@ void InitializeInterceptors() {
   FdInit();
 }
 
-void internal_start_thread(void(*func)(void *arg), void *arg) {
+void *internal_start_thread(void(*func)(void *arg), void *arg) {
   // Start the thread with signals blocked, otherwise it can steal user signals.
   __sanitizer_sigset_t set, old;
   internal_sigfillset(&set);
   internal_sigprocmask(SIG_SETMASK, &set, &old);
   void *th;
   REAL(pthread_create)(&th, 0, (void*(*)(void *arg))func, arg);
-  REAL(pthread_detach)(th);
   internal_sigprocmask(SIG_SETMASK, &old, 0);
+  return th;
+}
+
+void internal_join_thread(void *th) {
+  REAL(pthread_join)(th, 0);
 }
 
 }  // namespace __tsan

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Thu Apr 24 08:09:17 2014
@@ -164,7 +164,8 @@ uptr ALWAYS_INLINE GetThreadTraceHeader(
   return p;
 }
 
-void internal_start_thread(void(*func)(void*), void *arg);
+void *internal_start_thread(void(*func)(void*), void *arg);
+void internal_join_thread(void *th);
 
 // Says whether the addr relates to a global var.
 // Guesses with high probability, may yield both false positives and negatives.

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=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Thu Apr 24 08:09:17 2014
@@ -120,8 +120,13 @@ static void MemoryProfiler(Context *ctx,
 }
 
 static void BackgroundThread(void *arg) {
+#ifndef TSAN_GO
   // This is a non-initialized non-user thread, nothing to see here.
-  ScopedIgnoreInterceptors ignore;
+  // We don't use ScopedIgnoreInterceptors, because we want ignores to be
+  // enabled even when the thread function exits (e.g. during pthread thread
+  // shutdown code).
+  cur_thread()->ignore_interceptors++;
+#endif
   const u64 kMs2Ns = 1000 * 1000;
 
   fd_t mprof_fd = kInvalidFd;
@@ -140,8 +145,10 @@ static void BackgroundThread(void *arg)
 
   u64 last_flush = NanoTime();
   uptr last_rss = 0;
-  for (int i = 0; ; i++) {
-    SleepForSeconds(1);
+  for (int i = 0;
+      atomic_load(&ctx->stop_background_thread, memory_order_relaxed) == 0;
+      i++) {
+    SleepForMillis(100);
     u64 now = NanoTime();
 
     // Flush memory if requested.
@@ -192,6 +199,16 @@ static void BackgroundThread(void *arg)
   }
 }
 
+static void StartBackgroundThread() {
+  ctx->background_thread = internal_start_thread(&BackgroundThread, 0);
+}
+
+static void StopBackgroundThread() {
+  atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);
+  internal_join_thread(ctx->background_thread);
+  ctx->background_thread = 0;
+}
+
 void DontNeedShadowFor(uptr addr, uptr size) {
   uptr shadow_beg = MemToShadow(addr);
   uptr shadow_end = MemToShadow(addr + size);
@@ -250,7 +267,8 @@ void Initialize(ThreadState *thr) {
   Symbolizer::Init(common_flags()->external_symbolizer_path);
   Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer);
 #endif
-  internal_start_thread(&BackgroundThread, 0);
+  StartBackgroundThread();
+  SetSandboxingCallback(StopBackgroundThread);
   if (flags()->detect_deadlocks)
     ctx->dd = DDetector::Create(flags());
 

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=207114&r1=207113&r2=207114&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Thu Apr 24 08:09:17 2014
@@ -536,6 +536,9 @@ struct Context {
   int nmissed_expected;
   atomic_uint64_t last_symbolize_time_ns;
 
+  void *background_thread;
+  atomic_uint32_t stop_background_thread;
+
   ThreadRegistry *thread_registry;
 
   Vector<RacyStacks> racy_stacks;





More information about the llvm-commits mailing list