[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, &param->frontier);
   ForEachChunk(CollectLeaksCb, &param->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, &param);
 
   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 &region,
                     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, &param);
 }

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