Skip to content

Commit aae707c

Browse files
frobtechpetrhosek
authored andcommitted
[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
1 parent 5d87b5d commit aae707c

File tree

4 files changed

+29
-23
lines changed

4 files changed

+29
-23
lines changed

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -443,25 +443,23 @@ void ProcessPC(Frontier *frontier) {
443443
}
444444

445445
// Sets the appropriate tag on each chunk.
446-
static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads) {
447-
// Holds the flood fill frontier.
448-
Frontier frontier;
446+
static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads,
447+
Frontier *frontier) {
448+
ForEachChunk(CollectIgnoredCb, frontier);
449+
ProcessGlobalRegions(frontier);
450+
ProcessThreads(suspended_threads, frontier);
451+
ProcessRootRegions(frontier);
452+
FloodFillTag(frontier, kReachable);
449453

450-
ForEachChunk(CollectIgnoredCb, &frontier);
451-
ProcessGlobalRegions(&frontier);
452-
ProcessThreads(suspended_threads, &frontier);
453-
ProcessRootRegions(&frontier);
454-
FloodFillTag(&frontier, kReachable);
455-
456-
CHECK_EQ(0, frontier.size());
457-
ProcessPC(&frontier);
454+
CHECK_EQ(0, frontier->size());
455+
ProcessPC(frontier);
458456

459457
// The check here is relatively expensive, so we do this in a separate flood
460458
// fill. That way we can skip the check for chunks that are reachable
461459
// otherwise.
462460
LOG_POINTERS("Processing platform-specific allocations.\n");
463-
ProcessPlatformSpecificAllocations(&frontier);
464-
FloodFillTag(&frontier, kReachable);
461+
ProcessPlatformSpecificAllocations(frontier);
462+
FloodFillTag(frontier, kReachable);
465463

466464
// Iterate over leaked chunks and mark those that are reachable from other
467465
// leaked chunks.
@@ -521,11 +519,6 @@ static void PrintMatchedSuppressions() {
521519
Printf("%s\n\n", line);
522520
}
523521

524-
struct CheckForLeaksParam {
525-
bool success;
526-
LeakReport leak_report;
527-
};
528-
529522
static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) {
530523
const InternalMmapVector<tid_t> &suspended_threads =
531524
*(const InternalMmapVector<tid_t> *)arg;
@@ -556,7 +549,7 @@ static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
556549
CHECK(param);
557550
CHECK(!param->success);
558551
ReportUnsuspendedThreads(suspended_threads);
559-
ClassifyAllChunks(suspended_threads);
552+
ClassifyAllChunks(suspended_threads, &param->frontier);
560553
ForEachChunk(CollectLeaksCb, &param->leak_report);
561554
// Clean up for subsequent leak checks. This assumes we did not overwrite any
562555
// kIgnored tags.
@@ -569,7 +562,6 @@ static bool CheckForLeaks() {
569562
return false;
570563
EnsureMainThreadIDIsCorrect();
571564
CheckForLeaksParam param;
572-
param.success = false;
573565
LockStuffAndStopTheWorld(CheckForLeaksCallback, &param);
574566

575567
if (!param.success) {

compiler-rt/lib/lsan/lsan_common.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,24 @@ struct RootRegion {
126126
uptr size;
127127
};
128128

129+
// LockStuffAndStopTheWorld can start to use Scan* calls to collect into
130+
// this Frontier vector before the StopTheWorldCallback actually runs.
131+
// This is used when the OS has a unified callback API for suspending
132+
// threads and enumerating roots.
133+
struct CheckForLeaksParam {
134+
Frontier frontier;
135+
LeakReport leak_report;
136+
bool success = false;
137+
};
138+
129139
InternalMmapVector<RootRegion> const *GetRootRegions();
130140
void ScanRootRegion(Frontier *frontier, RootRegion const &region,
131141
uptr region_begin, uptr region_end, bool is_readable);
142+
void ForEachExtraStackRangeCb(uptr begin, uptr end, void* arg);
132143
// Run stoptheworld while holding any platform-specific locks, as well as the
133144
// allocator and thread registry locks.
134-
void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void* argument);
145+
void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
146+
CheckForLeaksParam* argument);
135147

136148
void ScanRangeForPointers(uptr begin, uptr end,
137149
Frontier *frontier,

compiler-rt/lib/lsan/lsan_common_linux.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ static int LockStuffAndStopTheWorldCallback(struct dl_phdr_info *info,
134134
// while holding the libdl lock in the parent thread, we can safely reenter it
135135
// in the tracer. The solution is to run stoptheworld from a dl_iterate_phdr()
136136
// callback in the parent thread.
137-
void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) {
137+
void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
138+
CheckForLeaksParam *argument) {
138139
DoStopTheWorldParam param = {callback, argument};
139140
dl_iterate_phdr(LockStuffAndStopTheWorldCallback, &param);
140141
}

compiler-rt/lib/lsan/lsan_common_mac.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {
193193
// causes rare race conditions.
194194
void HandleLeaks() {}
195195

196-
void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) {
196+
void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
197+
CheckForLeaksParam *argument) {
197198
LockThreadRegistry();
198199
LockAllocator();
199200
StopTheWorld(callback, argument);

0 commit comments

Comments
 (0)