[compiler-rt] 2924189 - [LSAN] More LSAN interface tweaking.
Kirill Stoimenov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 12 15:44:20 PST 2023
Author: Kirill Stoimenov
Date: 2023-01-12T23:44:08Z
New Revision: 2924189233fdb724453ead4b94595107b1ce9cfa
URL: https://github.com/llvm/llvm-project/commit/2924189233fdb724453ead4b94595107b1ce9cfa
DIFF: https://github.com/llvm/llvm-project/commit/2924189233fdb724453ead4b94595107b1ce9cfa.diff
LOG: [LSAN] More LSAN interface tweaking.
Main goal is to remove thread registry dependency from the interface because HWASAN is using its own code to manage threads.
Reviewed By: vitalybuka, kstoimenov
Differential Revision: https://reviews.llvm.org/D140039
Added:
Modified:
compiler-rt/lib/asan/asan_allocator.cpp
compiler-rt/lib/asan/asan_thread.cpp
compiler-rt/lib/lsan/lsan_allocator.cpp
compiler-rt/lib/lsan/lsan_common.cpp
compiler-rt/lib/lsan/lsan_common.h
compiler-rt/lib/lsan/lsan_fuchsia.cpp
compiler-rt/lib/lsan/lsan_thread.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
index 52d7eff7281e..335de3383db0 100644
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -1153,33 +1153,6 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) {
return kIgnoreObjectSuccess;
}
-void GetAdditionalThreadContextPtrs(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 =
- reinterpret_cast<__asan::AsanThreadContext *>(tctx);
- __asan::AsanThread *asan_thread = atctx->thread;
-
- // 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>(asan_thread->get_arg());
- if (!thread_arg)
- return;
-
- auto ptrsVec = reinterpret_cast<InternalMmapVector<uptr> *>(ptrs);
- ptrsVec->push_back(thread_arg);
-}
-
} // namespace __lsan
// ---------------------- Interface ---------------- {{{1
diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp
index 4b5e4a33fbdd..10a1e8c4abc1 100644
--- a/compiler-rt/lib/asan/asan_thread.cpp
+++ b/compiler-rt/lib/asan/asan_thread.cpp
@@ -518,9 +518,41 @@ void ForEachExtraStackRange(tid_t os_id, RangeIteratorCallback callback,
fake_stack->ForEachFakeFrame(callback, arg);
}
-void RunCallbackForEachThreadLocked(__sanitizer::ThreadRegistry::ThreadCallback cb,
- void *arg) {
- GetAsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(cb, arg);
+static void GetAdditionalThreadContextPtrs(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 =
+ reinterpret_cast<__asan::AsanThreadContext *>(tctx);
+ __asan::AsanThread *asan_thread = atctx->thread;
+
+ // 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>(asan_thread->get_arg());
+ if (!thread_arg)
+ return;
+
+ auto ptrsVec = reinterpret_cast<InternalMmapVector<uptr> *>(ptrs);
+ ptrsVec->push_back(thread_arg);
+}
+
+void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) {
+ GetAsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
+ GetAdditionalThreadContextPtrs, ptrs);
+}
+
+void ReportUnsuspendedThreadsLocked(InternalMmapVector<tid_t> *threads) {
+ GetAsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
+ &ReportIfNotSuspended, threads);
}
void FinishThreadLocked(u32 tid) {
diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp
index 43928ad294e2..b18d829a1a2a 100644
--- a/compiler-rt/lib/lsan/lsan_allocator.cpp
+++ b/compiler-rt/lib/lsan/lsan_allocator.cpp
@@ -319,7 +319,7 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) {
}
}
-void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs) {
+void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *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.
diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index 33c590cd4069..0fe20011150e 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -371,7 +371,7 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE void __libc_iterate_dynamic_tls(
static void ProcessThreadRegistry(Frontier *frontier) {
InternalMmapVector<uptr> ptrs;
- RunCallbackForEachThreadLocked(GetAdditionalThreadContextPtrs, &ptrs);
+ GetAdditionalThreadContextPtrsLocked(&ptrs);
for (uptr i = 0; i < ptrs.size(); ++i) {
void *ptr = reinterpret_cast<void *>(ptrs[i]);
@@ -668,7 +668,7 @@ void LeakSuppressionContext::PrintMatchedSuppressions() {
Printf("%s\n\n", line);
}
-static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) {
+void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) {
const InternalMmapVector<tid_t> &suspended_threads =
*(const InternalMmapVector<tid_t> *)arg;
if (tctx->status == ThreadStatusRunning) {
@@ -695,8 +695,7 @@ static void ReportUnsuspendedThreads(
threads[i] = suspended_threads.GetThreadID(i);
Sort(threads.data(), threads.size());
-
- RunCallbackForEachThreadLocked(&ReportIfNotSuspended, &threads);
+ ReportUnsuspendedThreadsLocked(&threads);
}
# endif // !SANITIZER_FUCHSIA
diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index 089aa10155a0..add916c665dc 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -105,9 +105,9 @@ bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches);
void ForEachExtraStackRange(tid_t os_id, RangeIteratorCallback callback,
void *arg);
-
-void RunCallbackForEachThreadLocked(__sanitizer::ThreadRegistry::ThreadCallback cb,
- void *arg);
+void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs);
+void ReportUnsuspendedThreadsLocked(InternalMmapVector<tid_t> *threads);
+void FinishThreadLocked(u32 tid);
//// --------------------------------------------------------------------------
//// Allocator prototypes.
@@ -146,8 +146,6 @@ void ForEachChunk(ForEachChunkCallback callback, void *arg);
// Helper for __lsan_ignore_object().
IgnoreObjectResult IgnoreObjectLocked(const void *p);
-void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs);
-
// The rest of the LSan interface which is implemented by library.
struct ScopedStopTheWorldLock {
@@ -269,6 +267,7 @@ void DoLeakCheck();
void DoRecoverableLeakCheckVoid();
void DisableCounterUnderflow();
bool DisabledInThisThread();
+void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg);
// Used to implement __lsan::ScopedDisabler.
void DisableInThisThread();
diff --git a/compiler-rt/lib/lsan/lsan_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_fuchsia.cpp
index 1bcb748e7d2a..03ac0afbabff 100644
--- a/compiler-rt/lib/lsan/lsan_fuchsia.cpp
+++ b/compiler-rt/lib/lsan/lsan_fuchsia.cpp
@@ -68,7 +68,7 @@ void InitializeMainThread() {
}
void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {
- RunCallbackForEachThreadLocked(
+ GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
[](ThreadContextBase *tctx, void *arg) {
auto ctx = static_cast<ThreadContext *>(tctx);
static_cast<decltype(caches)>(arg)->push_back(ctx->cache_begin());
diff --git a/compiler-rt/lib/lsan/lsan_thread.cpp b/compiler-rt/lib/lsan/lsan_thread.cpp
index d04d9057b71b..02a873d5367a 100644
--- a/compiler-rt/lib/lsan/lsan_thread.cpp
+++ b/compiler-rt/lib/lsan/lsan_thread.cpp
@@ -87,9 +87,9 @@ ThreadRegistry *GetLsanThreadRegistryLocked() {
return thread_registry;
}
-void RunCallbackForEachThreadLocked(
- __sanitizer::ThreadRegistry::ThreadCallback cb, void *arg) {
- GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(cb, arg);
+void ReportUnsuspendedThreadsLocked(InternalMmapVector<tid_t> *threads) {
+ GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
+ &ReportIfNotSuspended, threads);
}
} // namespace __lsan
More information about the llvm-commits
mailing list