MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / ProcessThread

Function ProcessThread

system/lib/compiler-rt/lib/lsan/lsan_common.cpp:481–589  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

479// Scans thread data (stacks and TLS) for heap pointers.
480template <class Accessor>
481static void ProcessThread(tid_t os_id, uptr sp,
482 const InternalMmapVector<uptr> &registers,
483 InternalMmapVector<Range> &extra_ranges,
484 Frontier *frontier, Accessor &accessor) {
485 // `extra_ranges` is outside of the function and the loop to reused mapped
486 // memory.
487 CHECK(extra_ranges.empty());
488 LOG_THREADS("Processing thread %llu.\n", os_id);
489 uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end;
490 DTLS *dtls;
491 bool thread_found =
492 GetThreadRangesLocked(os_id, &stack_begin, &stack_end, &tls_begin,
493 &tls_end, &cache_begin, &cache_end, &dtls);
494 if (!thread_found) {
495 // If a thread can't be found in the thread registry, it's probably in the
496 // process of destruction. Log this event and move on.
497 LOG_THREADS("Thread %llu not found in registry.\n", os_id);
498 return;
499 }
500
501 if (!sp)
502 sp = stack_begin;
503
504 if (flags()->use_registers) {
505 uptr registers_begin = reinterpret_cast<uptr>(registers.data());
506 uptr registers_end =
507 reinterpret_cast<uptr>(registers.data() + registers.size());
508 ScanForPointers(registers_begin, registers_end, frontier, "REGISTERS",
509 kReachable, accessor);
510 }
511
512 if (flags()->use_stacks) {
513 LOG_THREADS("Stack at %p-%p (SP = %p).\n", (void *)stack_begin,
514 (void *)stack_end, (void *)sp);
515 if (sp < stack_begin || sp >= stack_end) {
516 // SP is outside the recorded stack range (e.g. the thread is running a
517 // signal handler on alternate stack, or swapcontext was used).
518 // Again, consider the entire stack range to be reachable.
519 LOG_THREADS("WARNING: stack pointer not in stack range.\n");
520 uptr page_size = GetPageSizeCached();
521 int skipped = 0;
522 while (stack_begin < stack_end &&
523 !IsAccessibleMemoryRange(stack_begin, 1)) {
524 skipped++;
525 stack_begin += page_size;
526 }
527 LOG_THREADS("Skipped %d guard page(s) to obtain stack %p-%p.\n", skipped,
528 (void *)stack_begin, (void *)stack_end);
529 } else {
530 // Shrink the stack range to ignore out-of-scope values.
531 stack_begin = sp;
532 }
533 ScanForPointers(stack_begin, stack_end, frontier, "STACK", kReachable,
534 accessor);
535 GetThreadExtraStackRangesLocked(os_id, &extra_ranges);
536 ScanRanges(extra_ranges, frontier, "FAKE STACK", accessor);
537 }
538

Callers 1

ProcessThreadsFunction · 0.85

Calls 14

ScanForPointersFunction · 0.85
GetPageSizeCachedFunction · 0.85
ScanRangesFunction · 0.85
DTLSInDestructionFunction · 0.85
ForEachDVTFunction · 0.85
GetThreadRangesLockedFunction · 0.70
flagsFunction · 0.70
sizeMethod · 0.65
push_backMethod · 0.65
IsAccessibleMemoryRangeFunction · 0.50
emptyMethod · 0.45

Tested by

no test coverage detected