@@ -293,6 +293,27 @@ struct DirectMemoryAccessor {
293
293
void Init (uptr begin, uptr end) {};
294
294
void *LoadPtr (uptr p) const { return *reinterpret_cast <void **>(p); }
295
295
};
296
+
297
+ struct CopyMemoryAccessor {
298
+ void Init (uptr begin, uptr end) {
299
+ this ->begin = begin;
300
+ buffer.clear ();
301
+ buffer.resize (end - begin);
302
+ MemCpyAccessible (buffer.data (), reinterpret_cast <void *>(begin),
303
+ buffer.size ());
304
+ };
305
+
306
+ void *LoadPtr (uptr p) const {
307
+ uptr offset = p - begin;
308
+ CHECK_LE (offset + sizeof (void *), reinterpret_cast <uptr>(buffer.size ()));
309
+ return *reinterpret_cast <void **>(offset +
310
+ reinterpret_cast <uptr>(buffer.data ()));
311
+ }
312
+
313
+ private:
314
+ uptr begin;
315
+ InternalMmapVector<char > buffer;
316
+ };
296
317
} // namespace
297
318
298
319
// Scans the memory range, looking for byte patterns that point into allocator
@@ -535,6 +556,7 @@ static void ProcessThread(tid_t os_id, uptr sp,
535
556
static void ProcessThreads (SuspendedThreadsList const &suspended_threads,
536
557
Frontier *frontier, tid_t caller_tid,
537
558
uptr caller_sp) {
559
+ InternalMmapVector<tid_t > done_threads;
538
560
InternalMmapVector<uptr> registers;
539
561
InternalMmapVector<Range> extra_ranges;
540
562
for (uptr i = 0 ; i < suspended_threads.ThreadCount (); i++) {
@@ -559,6 +581,25 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
559
581
560
582
DirectMemoryAccessor accessor;
561
583
ProcessThread (os_id, sp, registers, extra_ranges, frontier, accessor);
584
+ if (flags ()->use_detached )
585
+ done_threads.push_back (os_id);
586
+ }
587
+
588
+ if (flags ()->use_detached ) {
589
+ CopyMemoryAccessor accessor;
590
+ InternalMmapVector<tid_t > known_threads;
591
+ GetRunningThreadsLocked (&known_threads);
592
+ Sort (done_threads.data (), done_threads.size ());
593
+ for (tid_t os_id : known_threads) {
594
+ registers.clear ();
595
+ extra_ranges.clear ();
596
+
597
+ uptr i = InternalLowerBound (done_threads, os_id);
598
+ if (i >= done_threads.size () || done_threads[i] != os_id) {
599
+ uptr sp = (os_id == caller_tid) ? caller_sp : 0 ;
600
+ ProcessThread (os_id, sp, registers, extra_ranges, frontier, accessor);
601
+ }
602
+ }
562
603
}
563
604
564
605
// Add pointers reachable from ThreadContexts
0 commit comments