diff options
author | Kamil Rytarowski <n54@gmx.com> | 2017-11-29 10:23:59 +0000 |
---|---|---|
committer | Kamil Rytarowski <n54@gmx.com> | 2017-11-29 10:23:59 +0000 |
commit | 17c071e3dcbb1ee6d107a12096ec26750fb816c0 (patch) | |
tree | 2d20c90ed7a5ee621570df0fea0139a0992a34d9 /lib | |
parent | 71ea69d5c99c8ccb761d70ab75b04d746be24aea (diff) |
Defer StartBackgroundThread() and StopBackgroundThread() in TSan
Summary:
NetBSD cannot spawn new POSIX thread entities in early
libc and libpthread initialization stage. Defer this to the point
of intercepting the first pthread_create(3) call.
This is the last change that makes Thread Sanitizer functional
on NetBSD/amd64 without downstream patches.
********************
Testing Time: 64.91s
********************
Failing Tests (5):
ThreadSanitizer-x86_64 :: dtls.c
ThreadSanitizer-x86_64 :: ignore_lib5.cc
ThreadSanitizer-x86_64 :: ignored-interceptors-mmap.cc
ThreadSanitizer-x86_64 :: mutex_lock_destroyed.cc
ThreadSanitizer-x86_64 :: vfork.cc
Expected Passes : 290
Expected Failures : 1
Unsupported Tests : 83
Unexpected Failures: 5
Sponsored by <The NetBSD Foundation>
Reviewers: joerg, eugenis, dvyukov, vitalybuka
Reviewed By: dvyukov
Subscribers: kubamracek, llvm-commits, #sanitizers
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D40583
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319305 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 3 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.cc | 22 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.h | 1 |
3 files changed, 19 insertions, 7 deletions
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index c37692c64..f3c354fa2 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -974,6 +974,9 @@ extern "C" void *__tsan_thread_start_func(void *arg) { TSAN_INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), void * param) { SCOPED_INTERCEPTOR_RAW(pthread_create, th, attr, callback, param); + + MaybeSpawnBackgroundThread(); + if (ctx->after_multithreaded_fork) { if (flags()->die_after_fork) { Report("ThreadSanitizer: starting new threads after multi-threaded " diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc index 3635b8c29..8e12fb67f 100644 --- a/lib/tsan/rtl/tsan_rtl.cc +++ b/lib/tsan/rtl/tsan_rtl.cc @@ -384,13 +384,6 @@ void Initialize(ThreadState *thr) { #if !SANITIZER_GO InitializeLibIgnore(); Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); - // On MIPS, TSan initialization is run before - // __pthread_initialize_minimal_internal() is finished, so we can not spawn - // new threads. -#ifndef __mips__ - StartBackgroundThread(); - SetSandboxingCallback(StopBackgroundThread); -#endif #endif VPrintf(1, "***** Running under ThreadSanitizer v2 (pid %d) *****\n", @@ -419,6 +412,21 @@ void Initialize(ThreadState *thr) { OnInitialize(); } +void MaybeSpawnBackgroundThread() { + // On MIPS, TSan initialization is run before + // __pthread_initialize_minimal_internal() is finished, so we can not spawn + // new threads. +#if !SANITIZER_GO && !defined(__mips__) + static atomic_uint32_t bg_thread = {}; + if (atomic_load(&bg_thread, memory_order_relaxed) == 0 && + atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) { + StartBackgroundThread(); + SetSandboxingCallback(StopBackgroundThread); + } +#endif +} + + int Finalize(ThreadState *thr) { bool failed = false; diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h index 96b4e75a3..8967a4b52 100644 --- a/lib/tsan/rtl/tsan_rtl.h +++ b/lib/tsan/rtl/tsan_rtl.h @@ -700,6 +700,7 @@ void PrintCurrentStack(ThreadState *thr, uptr pc); void PrintCurrentStackSlow(uptr pc); // uses libunwind void Initialize(ThreadState *thr); +void MaybeSpawnBackgroundThread(); int Finalize(ThreadState *thr); void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write); |