Author: Dan Liew Date: 2021-01-22T19:26:02-08:00 New Revision: dd922bc2a62163cef442646974324943c551725e
URL: https://github.com/llvm/llvm-project/commit/dd922bc2a62163cef442646974324943c551725e DIFF: https://github.com/llvm/llvm-project/commit/dd922bc2a62163cef442646974324943c551725e.diff LOG: [LSan] Introduce a callback mechanism to allow adding data reachable from ThreadContexts to the frontier. This mechanism is intended to provide a way to treat the `arg` pointer of a created (but not yet started) thread as reachable. In future patches this will be implemented in `GetAdditionalThreadContextPtrs`. A separate implementation of `GetAdditionalThreadContextPtrs` exists for ASan and LSan runtimes because they need to be implemented differently in future patches. rdar://problem/63537240 Differential Revision: https://reviews.llvm.org/D95183 Added: Modified: compiler-rt/lib/asan/asan_allocator.cpp compiler-rt/lib/lsan/lsan_allocator.cpp compiler-rt/lib/lsan/lsan_common.cpp compiler-rt/lib/lsan/lsan_common.h Removed: ################################################################################ diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index 58b496a3ca4b..4da697835870 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -1183,6 +1183,16 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) { m->lsan_tag = __lsan::kIgnored; return kIgnoreObjectSuccess; } + +void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs) { + // This function can be used to treat memory reachable from `tctx` as live. + // This is useful for threads that have been created but not yet started. + + // This is currently a no-op because the ASan `pthread_create()` interceptor + // blocks until the child thread starts which keeps the thread's `arg` pointer + // live. +} + } // namespace __lsan // ---------------------- Interface ---------------- {{{1 diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp index d86c3921395c..70422957e6f3 100644 --- a/compiler-rt/lib/lsan/lsan_allocator.cpp +++ b/compiler-rt/lib/lsan/lsan_allocator.cpp @@ -309,6 +309,16 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) { return kIgnoreObjectInvalid; } } + +void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs) { + // This function can be used to treat memory reachable from `tctx` as live. + // This is useful for threads that have been created but not yet started. + + // This is currently a no-op because the LSan `pthread_create()` interceptor + // blocks until the child thread starts which keeps the thread's `arg` pointer + // live. +} + } // namespace __lsan using namespace __lsan; diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index ab7500ce32cf..d5b4132b24d5 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -253,6 +253,27 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_iterate_dynamic_tls( pid_t, void (*cb)(void *, void *, uptr, void *), void *); #endif +static void ProcessThreadRegistry(Frontier *frontier) { + InternalMmapVector<uptr> ptrs; + GetThreadRegistryLocked()->RunCallbackForEachThreadLocked( + GetAdditionalThreadContextPtrs, &ptrs); + + for (uptr i = 0; i < ptrs.size(); ++i) { + void *ptr = reinterpret_cast<void *>(ptrs[i]); + uptr chunk = PointsIntoChunk(ptr); + if (!chunk) + continue; + LsanMetadata m(chunk); + if (!m.allocated()) + continue; + + // Mark as reachable and add to frontier. + LOG_POINTERS("Treating pointer %p from ThreadContext as reachable\n", ptr); + m.set_tag(kReachable); + frontier->push_back(chunk); + } +} + // Scans thread data (stacks and TLS) for heap pointers. static void ProcessThreads(SuspendedThreadsList const &suspended_threads, Frontier *frontier) { @@ -364,6 +385,9 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads, #endif } } + + // Add pointers reachable from ThreadContexts + ProcessThreadRegistry(frontier); } #endif // SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index 05f380d4a5fa..b0ae6f020b63 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -50,6 +50,7 @@ namespace __sanitizer { class FlagParser; class ThreadRegistry; +class ThreadContextBase; struct DTLS; } @@ -142,6 +143,7 @@ InternalMmapVector<RootRegion> const *GetRootRegions(); void ScanRootRegion(Frontier *frontier, RootRegion const ®ion, uptr region_begin, uptr region_end, bool is_readable); void ForEachExtraStackRangeCb(uptr begin, uptr end, void* arg); +void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs); // Run stoptheworld while holding any platform-specific locks, as well as the // allocator and thread registry locks. void LockStuffAndStopTheWorld(StopTheWorldCallback callback, _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits