summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/asan/asan_thread.cc5
-rw-r--r--compiler-rt/lib/lsan/lsan_common.cc30
-rw-r--r--compiler-rt/lib/lsan/lsan_common.h2
-rw-r--r--compiler-rt/lib/lsan/lsan_thread.cc5
4 files changed, 40 insertions, 2 deletions
diff --git a/compiler-rt/lib/asan/asan_thread.cc b/compiler-rt/lib/asan/asan_thread.cc
index ad81512dff0..4a8779f0397 100644
--- a/compiler-rt/lib/asan/asan_thread.cc
+++ b/compiler-rt/lib/asan/asan_thread.cc
@@ -477,6 +477,11 @@ void UnlockThreadRegistry() {
__asan::asanThreadRegistry().Unlock();
}
+ThreadRegistry *GetThreadRegistryLocked() {
+ __asan::asanThreadRegistry().CheckLocked();
+ return &__asan::asanThreadRegistry();
+}
+
void EnsureMainThreadIDIsCorrect() {
__asan::EnsureMainThreadIDIsCorrect();
}
diff --git a/compiler-rt/lib/lsan/lsan_common.cc b/compiler-rt/lib/lsan/lsan_common.cc
index bdc825d767b..eaa5cadc8ff 100644
--- a/compiler-rt/lib/lsan/lsan_common.cc
+++ b/compiler-rt/lib/lsan/lsan_common.cc
@@ -15,14 +15,15 @@
#include "lsan_common.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_procmaps.h"
+#include "sanitizer_common/sanitizer_report_decorator.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_suppressions.h"
-#include "sanitizer_common/sanitizer_report_decorator.h"
+#include "sanitizer_common/sanitizer_thread_registry.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#if CAN_SANITIZE_LEAKS
@@ -526,11 +527,36 @@ struct CheckForLeaksParam {
LeakReport leak_report;
};
+static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) {
+ const InternalMmapVector<tid_t> &suspended_threads =
+ *(const InternalMmapVector<tid_t> *)arg;
+ if (tctx->status == ThreadStatusRunning) {
+ uptr i = InternalLowerBound(suspended_threads, 0, suspended_threads.size(),
+ tctx->os_id, CompareLess<int>());
+ if (i >= suspended_threads.size() || suspended_threads[i] != tctx->os_id)
+ Report("Running thread %d was not suspended. False leaks are possible.\n",
+ tctx->os_id);
+ };
+}
+
+static void ReportUnsuspendedThreads(
+ const SuspendedThreadsList &suspended_threads) {
+ InternalMmapVector<tid_t> threads(suspended_threads.ThreadCount());
+ for (uptr i = 0; i < suspended_threads.ThreadCount(); ++i)
+ threads[i] = suspended_threads.GetThreadID(i);
+
+ Sort(threads.data(), threads.size());
+
+ GetThreadRegistryLocked()->RunCallbackForEachThreadLocked(
+ &ReportIfNotSuspended, &threads);
+}
+
static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads,
void *arg) {
CheckForLeaksParam *param = reinterpret_cast<CheckForLeaksParam *>(arg);
CHECK(param);
CHECK(!param->success);
+ ReportUnsuspendedThreads(suspended_threads);
ClassifyAllChunks(suspended_threads);
ForEachChunk(CollectLeaksCb, &param->leak_report);
// Clean up for subsequent leak checks. This assumes we did not overwrite any
diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index 2bffed4a5a6..1d1e1e46243 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -47,6 +47,7 @@
namespace __sanitizer {
class FlagParser;
+class ThreadRegistry;
struct DTLS;
}
@@ -204,6 +205,7 @@ bool WordIsPoisoned(uptr addr);
// Wrappers for ThreadRegistry access.
void LockThreadRegistry();
void UnlockThreadRegistry();
+ThreadRegistry *GetThreadRegistryLocked();
bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
uptr *cache_end, DTLS **dtls);
diff --git a/compiler-rt/lib/lsan/lsan_thread.cc b/compiler-rt/lib/lsan/lsan_thread.cc
index 4404c8cc51d..a25aff37996 100644
--- a/compiler-rt/lib/lsan/lsan_thread.cc
+++ b/compiler-rt/lib/lsan/lsan_thread.cc
@@ -155,4 +155,9 @@ void UnlockThreadRegistry() {
thread_registry->Unlock();
}
+ThreadRegistry *GetThreadRegistryLocked() {
+ thread_registry->CheckLocked();
+ return thread_registry;
+}
+
} // namespace __lsan
OpenPOWER on IntegriCloud