Skip to content

Commit cc3f8f7

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.4
1 parent 7106de9 commit cc3f8f7

File tree

1 file changed

+48
-21
lines changed

1 file changed

+48
-21
lines changed

compiler-rt/lib/lsan/lsan_common.cpp

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -288,23 +288,32 @@ static inline bool MaybeUserPointer(uptr p) {
288288
# endif
289289
}
290290

291+
namespace {
292+
struct DirectLoader {
293+
void Init(uptr begin, uptr end) {};
294+
void *operator()(uptr p) const { return *reinterpret_cast<void **>(p); }
295+
};
296+
} // namespace
297+
291298
// Scans the memory range, looking for byte patterns that point into allocator
292299
// chunks. Marks those chunks with |tag| and adds them to |frontier|.
293300
// There are two usage modes for this function: finding reachable chunks
294301
// (|tag| = kReachable) and finding indirectly leaked chunks
295302
// (|tag| = kIndirectlyLeaked). In the second case, there's no flood fill,
296303
// so |frontier| = 0.
297-
void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier,
298-
const char *region_type, ChunkTag tag) {
304+
template <class S>
305+
void ScanForPointers(uptr begin, uptr end, Frontier *frontier,
306+
const char *region_type, ChunkTag tag, S &scanner) {
299307
CHECK(tag == kReachable || tag == kIndirectlyLeaked);
300308
const uptr alignment = flags()->pointer_alignment();
301309
LOG_POINTERS("Scanning %s range %p-%p.\n", region_type, (void *)begin,
302310
(void *)end);
311+
scanner.Init(begin, end);
303312
uptr pp = begin;
304313
if (pp % alignment)
305314
pp = pp + alignment - pp % alignment;
306315
for (; pp + sizeof(void *) <= end; pp += alignment) {
307-
void *p = *reinterpret_cast<void **>(pp);
316+
void *p = scanner(pp);
308317
# if SANITIZER_APPLE
309318
p = TransformPointer(p);
310319
# endif
@@ -339,6 +348,12 @@ void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier,
339348
}
340349
}
341350

351+
void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier,
352+
const char *region_type, ChunkTag tag) {
353+
DirectLoader scanner;
354+
ScanForPointers(begin, end, frontier, region_type, tag, scanner);
355+
}
356+
342357
// Scans a global range for pointers
343358
void ScanGlobalRange(uptr begin, uptr end, Frontier *frontier) {
344359
uptr allocator_begin = 0, allocator_end = 0;
@@ -356,14 +371,21 @@ void ScanGlobalRange(uptr begin, uptr end, Frontier *frontier) {
356371
}
357372
}
358373

359-
void ScanExtraStackRanges(const InternalMmapVector<Range> &ranges,
360-
Frontier *frontier) {
374+
template <class S>
375+
void ScanExtraStack(const InternalMmapVector<Range> &ranges, Frontier *frontier,
376+
S &scanner) {
361377
for (uptr i = 0; i < ranges.size(); i++) {
362-
ScanRangeForPointers(ranges[i].begin, ranges[i].end, frontier, "FAKE STACK",
363-
kReachable);
378+
ScanForPointers(ranges[i].begin, ranges[i].end, frontier, "FAKE STACK",
379+
kReachable, scanner);
364380
}
365381
}
366382

383+
void ScanExtraStackRanges(const InternalMmapVector<Range> &ranges,
384+
Frontier *frontier) {
385+
DirectLoader scanner;
386+
ScanExtraStack(ranges, frontier, scanner);
387+
}
388+
367389
# if SANITIZER_FUCHSIA
368390

369391
// Fuchsia handles all threads together with its own callback.
@@ -399,10 +421,11 @@ static void ProcessThreadRegistry(Frontier *frontier) {
399421
}
400422

401423
// Scans thread data (stacks and TLS) for heap pointers.
424+
template <class S>
402425
static void ProcessThread(tid_t os_id, uptr sp,
403426
const InternalMmapVector<uptr> &registers,
404427
InternalMmapVector<Range> &extra_ranges,
405-
Frontier *frontier) {
428+
Frontier *frontier, S &scanner) {
406429
// `extra_ranges` is outside of the function and the loop to reused mapped
407430
// memory.
408431
CHECK(extra_ranges.empty());
@@ -426,8 +449,8 @@ static void ProcessThread(tid_t os_id, uptr sp,
426449
uptr registers_begin = reinterpret_cast<uptr>(registers.data());
427450
uptr registers_end =
428451
reinterpret_cast<uptr>(registers.data() + registers.size());
429-
ScanRangeForPointers(registers_begin, registers_end, frontier, "REGISTERS",
430-
kReachable);
452+
ScanForPointers(registers_begin, registers_end, frontier, "REGISTERS",
453+
kReachable, scanner);
431454
}
432455

433456
if (flags()->use_stacks) {
@@ -451,9 +474,10 @@ static void ProcessThread(tid_t os_id, uptr sp,
451474
// Shrink the stack range to ignore out-of-scope values.
452475
stack_begin = sp;
453476
}
454-
ScanRangeForPointers(stack_begin, stack_end, frontier, "STACK", kReachable);
477+
ScanForPointers(stack_begin, stack_end, frontier, "STACK", kReachable,
478+
scanner);
455479
GetThreadExtraStackRangesLocked(os_id, &extra_ranges);
456-
ScanExtraStackRanges(extra_ranges, frontier);
480+
ScanExtraStack(extra_ranges, frontier, scanner);
457481
}
458482

459483
if (flags()->use_tls) {
@@ -463,21 +487,23 @@ static void ProcessThread(tid_t os_id, uptr sp,
463487
// otherwise, only scan the non-overlapping portions
464488
if (cache_begin == cache_end || tls_end < cache_begin ||
465489
tls_begin > cache_end) {
466-
ScanRangeForPointers(tls_begin, tls_end, frontier, "TLS", kReachable);
490+
ScanForPointers(tls_begin, tls_end, frontier, "TLS", kReachable,
491+
scanner);
467492
} else {
468493
if (tls_begin < cache_begin)
469-
ScanRangeForPointers(tls_begin, cache_begin, frontier, "TLS",
470-
kReachable);
494+
ScanForPointers(tls_begin, cache_begin, frontier, "TLS", kReachable,
495+
scanner);
471496
if (tls_end > cache_end)
472-
ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable);
497+
ScanForPointers(cache_end, tls_end, frontier, "TLS", kReachable,
498+
scanner);
473499
}
474500
}
475501
# if SANITIZER_ANDROID
476502
auto *cb = +[](void *dtls_begin, void *dtls_end, uptr /*dso_idd*/,
477503
void *arg) -> void {
478-
ScanRangeForPointers(
504+
ScanForPointers(
479505
reinterpret_cast<uptr>(dtls_begin), reinterpret_cast<uptr>(dtls_end),
480-
reinterpret_cast<Frontier *>(arg), "DTLS", kReachable);
506+
reinterpret_cast<Frontier *>(arg), "DTLS", kReachable, scanner);
481507
};
482508

483509
// FIXME: There might be a race-condition here (and in Bionic) if the
@@ -492,8 +518,8 @@ static void ProcessThread(tid_t os_id, uptr sp,
492518
if (dtls_beg < dtls_end) {
493519
LOG_THREADS("DTLS %d at %p-%p.\n", id, (void *)dtls_beg,
494520
(void *)dtls_end);
495-
ScanRangeForPointers(dtls_beg, dtls_end, frontier, "DTLS",
496-
kReachable);
521+
ScanForPointers(dtls_beg, dtls_end, frontier, "DTLS", kReachable,
522+
scanner);
497523
}
498524
});
499525
} else {
@@ -530,7 +556,8 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
530556
if (os_id == caller_tid)
531557
sp = caller_sp;
532558

533-
ProcessThread(os_id, sp, registers, extra_ranges, frontier);
559+
DirectLoader scanner;
560+
ProcessThread(os_id, sp, registers, extra_ranges, frontier, scanner);
534561
}
535562

536563
// Add pointers reachable from ThreadContexts

0 commit comments

Comments
 (0)