diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2014-04-24 13:09:17 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2014-04-24 13:09:17 +0000 |
commit | b7ebc537727b8e7db68ee00730682165dcefef1e (patch) | |
tree | 625b988c738e50c5351094a8013d221961b4929b | |
parent | 34ad1a1085e6a128125a4ee2f1f7b362f029fb7f (diff) | |
download | bcm5719-llvm-b7ebc537727b8e7db68ee00730682165dcefef1e.tar.gz bcm5719-llvm-b7ebc537727b8e7db68ee00730682165dcefef1e.zip |
tsan: stop background thread when sandbox is enabled
Fixes https://code.google.com/p/thread-sanitizer/issues/detail?id=56
llvm-svn: 207114
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.cc | 7 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/go/tsan_go.cc | 6 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 8 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_platform.h | 3 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.cc | 26 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.h | 3 |
7 files changed, 46 insertions, 8 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc index 0eab824463d..c0c7748a7c3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc @@ -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 char *path) { 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) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 00c686ead64..8fa41679f4e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -184,6 +184,7 @@ bool StackSizeIsUnlimited(); void SetStackSizeLimitInBytes(uptr limit); void AdjustStackSize(void *attr); void PrepareForSandboxing(); +void SetSandboxingCallback(void (*f)()); void InitTlsSize(); uptr GetTlsSize(); diff --git a/compiler-rt/lib/tsan/go/tsan_go.cc b/compiler-rt/lib/tsan/go/tsan_go.cc index 3f168572720..e7761fee3c6 100644 --- a/compiler-rt/lib/tsan/go/tsan_go.cc +++ b/compiler-rt/lib/tsan/go/tsan_go.cc @@ -28,7 +28,11 @@ bool IsExpectedReport(uptr addr, uptr size) { 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) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index b9f02b9d967..b545f8c52bb 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -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 diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h index e960d5d99e2..7abe5f0d706 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -164,7 +164,8 @@ uptr ALWAYS_INLINE GetThreadTraceHeader(int tid) { 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. diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc index b0ae2dd5936..33b9f0bc2c8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc @@ -120,8 +120,13 @@ static void MemoryProfiler(Context *ctx, fd_t fd, int i) { } 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()); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index f862e5213a0..c542bd2bc68 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -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; |