summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2017-11-29 10:23:59 +0000
committerKamil Rytarowski <n54@gmx.com>2017-11-29 10:23:59 +0000
commit17c071e3dcbb1ee6d107a12096ec26750fb816c0 (patch)
tree2d20c90ed7a5ee621570df0fea0139a0992a34d9 /lib
parent71ea69d5c99c8ccb761d70ab75b04d746be24aea (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.cc3
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc22
-rw-r--r--lib/tsan/rtl/tsan_rtl.h1
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);