From 733d50b4864068c8d2dd08b698909d44c49479f1 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Thu, 17 Oct 2024 18:21:24 -0700 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 [skip ci] --- compiler-rt/lib/lsan/lsan_common.cpp | 70 +++++++++++++++++++--------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index 721db7872cce8..9aed36b96ce92 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -288,23 +288,33 @@ static inline bool MaybeUserPointer(uptr p) { # endif } +namespace { +struct DirectMemoryAccessor { + void Init(uptr begin, uptr end) {}; + void *LoadPtr(uptr p) const { return *reinterpret_cast(p); } +}; +} // namespace + // Scans the memory range, looking for byte patterns that point into allocator // chunks. Marks those chunks with |tag| and adds them to |frontier|. // There are two usage modes for this function: finding reachable chunks // (|tag| = kReachable) and finding indirectly leaked chunks // (|tag| = kIndirectlyLeaked). In the second case, there's no flood fill, // so |frontier| = 0. -void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier, - const char *region_type, ChunkTag tag) { +template +void ScanForPointers(uptr begin, uptr end, Frontier *frontier, + const char *region_type, ChunkTag tag, + Accessor &accessor) { CHECK(tag == kReachable || tag == kIndirectlyLeaked); const uptr alignment = flags()->pointer_alignment(); LOG_POINTERS("Scanning %s range %p-%p.\n", region_type, (void *)begin, (void *)end); + accessor.Init(begin, end); uptr pp = begin; if (pp % alignment) pp = pp + alignment - pp % alignment; for (; pp + sizeof(void *) <= end; pp += alignment) { - void *p = *reinterpret_cast(pp); + void *p = accessor.LoadPtr(pp); # if SANITIZER_APPLE p = TransformPointer(p); # endif @@ -339,6 +349,12 @@ void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier, } } +void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier, + const char *region_type, ChunkTag tag) { + DirectMemoryAccessor accessor; + ScanForPointers(begin, end, frontier, region_type, tag, accessor); +} + // Scans a global range for pointers void ScanGlobalRange(uptr begin, uptr end, Frontier *frontier) { uptr allocator_begin = 0, allocator_end = 0; @@ -356,14 +372,21 @@ void ScanGlobalRange(uptr begin, uptr end, Frontier *frontier) { } } -void ScanExtraStackRanges(const InternalMmapVector &ranges, - Frontier *frontier) { +template +void ScanExtraStack(const InternalMmapVector &ranges, Frontier *frontier, + Accessor &accessor) { for (uptr i = 0; i < ranges.size(); i++) { - ScanRangeForPointers(ranges[i].begin, ranges[i].end, frontier, "FAKE STACK", - kReachable); + ScanForPointers(ranges[i].begin, ranges[i].end, frontier, "FAKE STACK", + kReachable, accessor); } } +void ScanExtraStackRanges(const InternalMmapVector &ranges, + Frontier *frontier) { + DirectMemoryAccessor accessor; + ScanExtraStack(ranges, frontier, accessor); +} + # if SANITIZER_FUCHSIA // Fuchsia handles all threads together with its own callback. @@ -399,10 +422,11 @@ static void ProcessThreadRegistry(Frontier *frontier) { } // Scans thread data (stacks and TLS) for heap pointers. +template static void ProcessThread(tid_t os_id, uptr sp, const InternalMmapVector ®isters, InternalMmapVector &extra_ranges, - Frontier *frontier) { + Frontier *frontier, Accessor &accessor) { // `extra_ranges` is outside of the function and the loop to reused mapped // memory. CHECK(extra_ranges.empty()); @@ -426,8 +450,8 @@ static void ProcessThread(tid_t os_id, uptr sp, uptr registers_begin = reinterpret_cast(registers.data()); uptr registers_end = reinterpret_cast(registers.data() + registers.size()); - ScanRangeForPointers(registers_begin, registers_end, frontier, "REGISTERS", - kReachable); + ScanForPointers(registers_begin, registers_end, frontier, "REGISTERS", + kReachable, accessor); } if (flags()->use_stacks) { @@ -451,9 +475,10 @@ static void ProcessThread(tid_t os_id, uptr sp, // Shrink the stack range to ignore out-of-scope values. stack_begin = sp; } - ScanRangeForPointers(stack_begin, stack_end, frontier, "STACK", kReachable); + ScanForPointers(stack_begin, stack_end, frontier, "STACK", kReachable, + accessor); GetThreadExtraStackRangesLocked(os_id, &extra_ranges); - ScanExtraStackRanges(extra_ranges, frontier); + ScanExtraStack(extra_ranges, frontier, accessor); } if (flags()->use_tls) { @@ -463,21 +488,23 @@ static void ProcessThread(tid_t os_id, uptr sp, // otherwise, only scan the non-overlapping portions if (cache_begin == cache_end || tls_end < cache_begin || tls_begin > cache_end) { - ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable); + ScanForPointers(tls_begin, tls_end, frontier, "TLS", kReachable, + accessor); } else { if (tls_begin < cache_begin) - ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS", - kReachable); + ScanForPointers(tls_begin, cache_begin, frontier, "TLS", kReachable, + accessor); if (tls_end > cache_end) - ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable); + ScanForPointers(cache_end, tls_end, frontier, "TLS", kReachable, + accessor); } } # if SANITIZER_ANDROID auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/, void *arg) -> void { - ScanRangeForPointers( + ScanForPointers( reinterpret_cast(dtls_begin), reinterpret_cast(dtls_end), - reinterpret_cast(arg), "DTLS", kReachable); + reinterpret_cast(arg), "DTLS", kReachable, accessor); }; // FIXME: There might be a race-condition here (and in Bionic) if the @@ -492,8 +519,8 @@ static void ProcessThread(tid_t os_id, uptr sp, if (dtls_beg < dtls_end) { LOG_THREADS("DTLS %d at %p-%p.\n", id, (void *)dtls_beg, (void *)dtls_end); - ScanRangeForPointers(dtls_beg, dtls_end, frontier, "DTLS", - kReachable); + ScanForPointers(dtls_beg, dtls_end, frontier, "DTLS", kReachable, + accessor); } }); } else { @@ -530,7 +557,8 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads, if (os_id == caller_tid) sp = caller_sp; - ProcessThread(os_id, sp, registers, extra_ranges, frontier); + DirectMemoryAccessor accessor; + ProcessThread(os_id, sp, registers, extra_ranges, frontier, accessor); } // Add pointers reachable from ThreadContexts From 8e6448fbe62dd4236746bef0d2e389a822aaec77 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Thu, 17 Oct 2024 18:40:48 -0700 Subject: [PATCH 2/2] naming Created using spr 1.3.4 --- compiler-rt/lib/lsan/lsan_common.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index 8f16ff6c815c3..93fe1475e16bf 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -294,7 +294,7 @@ struct DirectMemoryAccessor { void *LoadPtr(uptr p) const { return *reinterpret_cast(p); } }; -struct CopyLoader { +struct CopyMemoryAccessor { void Init(uptr begin, uptr end) { this->begin = begin; buffer.clear(); @@ -585,7 +585,7 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads, } if (flags()->use_detached) { - CopyLoader accessor; + CopyMemoryAccessor accessor; InternalMmapVector known_threads; GetRunningThreadsLocked(&known_threads); Sort(done_threads.data(), done_threads.size());