Index: lib/tsan/rtl/tsan_interceptors.cc =================================================================== --- lib/tsan/rtl/tsan_interceptors.cc +++ lib/tsan/rtl/tsan_interceptors.cc @@ -974,6 +974,18 @@ TSAN_INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), void * param) { SCOPED_INTERCEPTOR_RAW(pthread_create, th, attr, callback, param); + +#if !SANITIZER_GO && !defined(__mips__) + static atomic_uint32_t bg_thread = {}; + u32 cond = atomic_load(&bg_thread, memory_order_acquire); + if (cond == 0) { + if (atomic_compare_exchange_strong(&bg_thread, &cond, 1, + memory_order_acq_rel)) { + TSanSpawnBackgroundThread(); + } + } +#endif + if (ctx->after_multithreaded_fork) { if (flags()->die_after_fork) { Report("ThreadSanitizer: starting new threads after multi-threaded " Index: lib/tsan/rtl/tsan_rtl.h =================================================================== --- lib/tsan/rtl/tsan_rtl.h +++ lib/tsan/rtl/tsan_rtl.h @@ -700,6 +700,9 @@ void PrintCurrentStackSlow(uptr pc); // uses libunwind void Initialize(ThreadState *thr); +#if !SANITIZER_GO && !defined(__mips__) +void TSanSpawnBackgroundThread(void); +#endif int Finalize(ThreadState *thr); void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write); Index: lib/tsan/rtl/tsan_rtl.cc =================================================================== --- lib/tsan/rtl/tsan_rtl.cc +++ lib/tsan/rtl/tsan_rtl.cc @@ -384,13 +384,6 @@ #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,17 @@ OnInitialize(); } +#if !SANITIZER_GO && !defined(__mips__) +void TSanSpawnBackgroundThread(void) { + // On MIPS, TSan initialization is run before + // __pthread_initialize_minimal_internal() is finished, so we can not spawn + // new threads. + StartBackgroundThread(); + SetSandboxingCallback(StopBackgroundThread); +} +#endif + + int Finalize(ThreadState *thr) { bool failed = false;