Index: compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -209,27 +209,25 @@ bool ThreadSuspender::SuspendAllThreads() { ThreadLister thread_lister(pid_); - bool added_threads; - bool first_iteration = true; + InternalMmapVector prev; + prev.reserve(128); InternalMmapVector threads; threads.reserve(128); - do { - // Run through the directory entries once. - added_threads = false; + // We can't get consistent thread list from /proc/, so to avoid missing + // threads we will try to list them at least 3 times after we suspended new + // one or received different list from the lister. + // TODO(vitalybuka): Start with the current content of the thread registry. + for (int i = 0; i < 3; ++i) { + bool added_threads = false; if (!thread_lister.ListThreads(&threads)) { ResumeAllThreads(); return false; } for (int tid : threads) - if (SuspendThread(tid)) - added_threads = true; - if (first_iteration && !added_threads) { - // Detach threads and fail. - ResumeAllThreads(); - return false; - } - first_iteration = false; - } while (added_threads); + if (SuspendThread(tid)) added_threads = true; + if (added_threads || prev != threads) i = -1; + prev.swap(threads); + } return true; }