diff options
Diffstat (limited to 'compiler-rt/lib/asan/asan_thread.cpp')
-rw-r--r-- | compiler-rt/lib/asan/asan_thread.cpp | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp index 343fd079fa02..a1734a6f896d 100644 --- a/compiler-rt/lib/asan/asan_thread.cpp +++ b/compiler-rt/lib/asan/asan_thread.cpp @@ -41,8 +41,6 @@ void AsanThreadContext::OnFinished() { } static ThreadRegistry *asan_thread_registry; -static ThreadArgRetval *thread_data; - static Mutex mu_for_thread_context; static LowLevelAllocator allocator_for_thread_context; @@ -65,12 +63,9 @@ static void InitThreads() { // MIPS requires aligned address static ALIGNED(alignof( ThreadRegistry)) char thread_registry_placeholder[sizeof(ThreadRegistry)]; - static ALIGNED(alignof( - ThreadArgRetval)) char thread_data_placeholder[sizeof(ThreadArgRetval)]; asan_thread_registry = new (thread_registry_placeholder) ThreadRegistry(GetAsanThreadContext); - thread_data = new (thread_data_placeholder) ThreadArgRetval(); initialized = true; } @@ -79,11 +74,6 @@ ThreadRegistry &asanThreadRegistry() { return *asan_thread_registry; } -ThreadArgRetval &asanThreadArgRetval() { - InitThreads(); - return *thread_data; -} - AsanThreadContext *GetThreadContextByTidLocked(u32 tid) { return static_cast<AsanThreadContext *>( asanThreadRegistry().GetThreadLocked(tid)); @@ -494,15 +484,9 @@ __asan::AsanThread *GetAsanThreadByOsIDLocked(tid_t os_id) { // --- Implementation of LSan-specific functions --- {{{1 namespace __lsan { -void LockThreadRegistry() { - __asan::asanThreadRegistry().Lock(); - __asan::asanThreadArgRetval().Lock(); -} +void LockThreadRegistry() { __asan::asanThreadRegistry().Lock(); } -void UnlockThreadRegistry() { - __asan::asanThreadArgRetval().Unlock(); - __asan::asanThreadRegistry().Unlock(); -} +void UnlockThreadRegistry() { __asan::asanThreadRegistry().Unlock(); } static ThreadRegistry *GetAsanThreadRegistryLocked() { __asan::asanThreadRegistry().CheckLocked(); @@ -557,7 +541,33 @@ void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) { } void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) { - __asan::asanThreadArgRetval().GetAllPtrsLocked(ptrs); + GetAsanThreadRegistryLocked()->RunCallbackForEachThreadLocked( + [](ThreadContextBase *tctx, void *ptrs) { + // Look for the arg pointer of threads that have been created or are + // running. This is necessary to prevent false positive leaks due to the + // AsanThread holding the only live reference to a heap object. This + // can happen because the `pthread_create()` interceptor doesn't wait + // for the child thread to start before returning and thus loosing the + // the only live reference to the heap object on the stack. + + __asan::AsanThreadContext *atctx = + static_cast<__asan::AsanThreadContext *>(tctx); + + // Note ThreadStatusRunning is required because there is a small window + // where the thread status switches to `ThreadStatusRunning` but the + // `arg` pointer still isn't on the stack yet. + if (atctx->status != ThreadStatusCreated && + atctx->status != ThreadStatusRunning) + return; + + uptr thread_arg = reinterpret_cast<uptr>(atctx->thread->get_arg()); + if (!thread_arg) + return; + + auto ptrsVec = reinterpret_cast<InternalMmapVector<uptr> *>(ptrs); + ptrsVec->push_back(thread_arg); + }, + ptrs); } void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) { |