[compiler-rt] aae707c - [lsan] Expose Frontier object to OS-specific LockStuffAndStopTheWorld callback
Petr Hosek via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 24 16:53:44 PST 2020
Author: Roland McGrath
Date: 2020-01-24T16:53:35-08:00
New Revision: aae707cd881f35d1d191f03ed7ef3b5b394e8ddb
URL: https://github.com/llvm/llvm-project/commit/aae707cd881f35d1d191f03ed7ef3b5b394e8ddb
DIFF: https://github.com/llvm/llvm-project/commit/aae707cd881f35d1d191f03ed7ef3b5b394e8ddb.diff
LOG: [lsan] Expose Frontier object to OS-specific LockStuffAndStopTheWorld callback
This is a small refactoring to prepare for porting LSan to Fuchsia.
On Fuchsia, the system supplies a unified API for suspending threads and
enumerating roots from OS-specific places like thread state and global data
ranges. So its LockStuffAndStopTheWorld implementation will make specific
callbacks for all the OS-specific root collection work before making the
common callback that includes the actual leak-checking logic.
Patch By: mcgrathr
Differential Revision: https://reviews.llvm.org/D72988
Added:
Modified:
compiler-rt/lib/lsan/lsan_common.cpp
compiler-rt/lib/lsan/lsan_common.h
compiler-rt/lib/lsan/lsan_common_linux.cpp
compiler-rt/lib/lsan/lsan_common_mac.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index 9ff9f4c5d1c9..aeaf0a39fde5 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -443,25 +443,23 @@ void ProcessPC(Frontier *frontier) {
}
// Sets the appropriate tag on each chunk.
-static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads) {
- // Holds the flood fill frontier.
- Frontier frontier;
+static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads,
+ Frontier *frontier) {
+ ForEachChunk(CollectIgnoredCb, frontier);
+ ProcessGlobalRegions(frontier);
+ ProcessThreads(suspended_threads, frontier);
+ ProcessRootRegions(frontier);
+ FloodFillTag(frontier, kReachable);
- ForEachChunk(CollectIgnoredCb, &frontier);
- ProcessGlobalRegions(&frontier);
- ProcessThreads(suspended_threads, &frontier);
- ProcessRootRegions(&frontier);
- FloodFillTag(&frontier, kReachable);
-
- CHECK_EQ(0, frontier.size());
- ProcessPC(&frontier);
+ CHECK_EQ(0, frontier->size());
+ ProcessPC(frontier);
// The check here is relatively expensive, so we do this in a separate flood
// fill. That way we can skip the check for chunks that are reachable
// otherwise.
LOG_POINTERS("Processing platform-specific allocations.\n");
- ProcessPlatformSpecificAllocations(&frontier);
- FloodFillTag(&frontier, kReachable);
+ ProcessPlatformSpecificAllocations(frontier);
+ FloodFillTag(frontier, kReachable);
// Iterate over leaked chunks and mark those that are reachable from other
// leaked chunks.
@@ -521,11 +519,6 @@ static void PrintMatchedSuppressions() {
Printf("%s\n\n", line);
}
-struct CheckForLeaksParam {
- bool success;
- LeakReport leak_report;
-};
-
static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) {
const InternalMmapVector<tid_t> &suspended_threads =
*(const InternalMmapVector<tid_t> *)arg;
@@ -556,7 +549,7 @@ static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
CHECK(param);
CHECK(!param->success);
ReportUnsuspendedThreads(suspended_threads);
- ClassifyAllChunks(suspended_threads);
+ ClassifyAllChunks(suspended_threads, ¶m->frontier);
ForEachChunk(CollectLeaksCb, ¶m->leak_report);
// Clean up for subsequent leak checks. This assumes we did not overwrite any
// kIgnored tags.
@@ -569,7 +562,6 @@ static bool CheckForLeaks() {
return false;
EnsureMainThreadIDIsCorrect();
CheckForLeaksParam param;
- param.success = false;
LockStuffAndStopTheWorld(CheckForLeaksCallback, ¶m);
if (!param.success) {
diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index d24abe31b71b..41075d658456 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -126,12 +126,24 @@ struct RootRegion {
uptr size;
};
+// LockStuffAndStopTheWorld can start to use Scan* calls to collect into
+// this Frontier vector before the StopTheWorldCallback actually runs.
+// This is used when the OS has a unified callback API for suspending
+// threads and enumerating roots.
+struct CheckForLeaksParam {
+ Frontier frontier;
+ LeakReport leak_report;
+ bool success = false;
+};
+
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);
// Run stoptheworld while holding any platform-specific locks, as well as the
// allocator and thread registry locks.
-void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void* argument);
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
+ CheckForLeaksParam* argument);
void ScanRangeForPointers(uptr begin, uptr end,
Frontier *frontier,
diff --git a/compiler-rt/lib/lsan/lsan_common_linux.cpp b/compiler-rt/lib/lsan/lsan_common_linux.cpp
index ea1a4a2f569d..c97ef31593df 100644
--- a/compiler-rt/lib/lsan/lsan_common_linux.cpp
+++ b/compiler-rt/lib/lsan/lsan_common_linux.cpp
@@ -134,7 +134,8 @@ static int LockStuffAndStopTheWorldCallback(struct dl_phdr_info *info,
// while holding the libdl lock in the parent thread, we can safely reenter it
// in the tracer. The solution is to run stoptheworld from a dl_iterate_phdr()
// callback in the parent thread.
-void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) {
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
+ CheckForLeaksParam *argument) {
DoStopTheWorldParam param = {callback, argument};
dl_iterate_phdr(LockStuffAndStopTheWorldCallback, ¶m);
}
diff --git a/compiler-rt/lib/lsan/lsan_common_mac.cpp b/compiler-rt/lib/lsan/lsan_common_mac.cpp
index c1804e93c11d..8516a176eb46 100644
--- a/compiler-rt/lib/lsan/lsan_common_mac.cpp
+++ b/compiler-rt/lib/lsan/lsan_common_mac.cpp
@@ -193,7 +193,8 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {
// causes rare race conditions.
void HandleLeaks() {}
-void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) {
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
+ CheckForLeaksParam *argument) {
LockThreadRegistry();
LockAllocator();
StopTheWorld(callback, argument);
More information about the llvm-commits
mailing list