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 | 166a37ab16749fbb710b41a2ac4c07ed4c3defaf (patch) | |
tree | 1f237d0445445238a14148d4e211c50deab1cd31 /lib/tsan/rtl | |
parent | 5308bd7973e489d2dc2658aafd4223067fc71f5e (diff) |
tsan: stop background thread when sandbox is enabled
Fixes https://code.google.com/p/thread-sanitizer/issues/detail?id=56
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@207114 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/rtl')
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 8 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform.h | 3 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.cc | 26 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.h | 3 |
4 files changed, 33 insertions, 7 deletions
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index b9f02b9d9..b545f8c52 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/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/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h index e960d5d99..7abe5f0d7 100644 --- a/lib/tsan/rtl/tsan_platform.h +++ b/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/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc index b0ae2dd59..33b9f0bc2 100644 --- a/lib/tsan/rtl/tsan_rtl.cc +++ b/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/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h index f862e5213..c542bd2bc 100644 --- a/lib/tsan/rtl/tsan_rtl.h +++ b/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; |