@@ -293,6 +293,27 @@ struct DirectMemoryAccessor {
293293 void Init (uptr begin, uptr end) {};
294294 void *LoadPtr (uptr p) const { return *reinterpret_cast <void **>(p); }
295295};
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+ };
296317} // namespace
297318
298319// 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,
535556static void ProcessThreads (SuspendedThreadsList const &suspended_threads,
536557 Frontier *frontier, tid_t caller_tid,
537558 uptr caller_sp) {
559+ InternalMmapVector<tid_t > done_threads;
538560 InternalMmapVector<uptr> registers;
539561 InternalMmapVector<Range> extra_ranges;
540562 for (uptr i = 0 ; i < suspended_threads.ThreadCount (); i++) {
@@ -559,6 +581,25 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads,
559581
560582 DirectMemoryAccessor accessor;
561583 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+ }
562603 }
563604
564605 // Add pointers reachable from ThreadContexts
0 commit comments