summaryrefslogtreecommitdiff
path: root/lib/lsan
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lsan')
-rw-r--r--lib/lsan/lsan.cpp (renamed from lib/lsan/lsan.cc)6
-rw-r--r--lib/lsan/lsan_allocator.cpp (renamed from lib/lsan/lsan_allocator.cc)2
-rw-r--r--lib/lsan/lsan_common.cpp (renamed from lib/lsan/lsan_common.cc)18
-rw-r--r--lib/lsan/lsan_common.h5
-rw-r--r--lib/lsan/lsan_common_linux.cpp (renamed from lib/lsan/lsan_common_linux.cc)14
-rw-r--r--lib/lsan/lsan_common_mac.cpp (renamed from lib/lsan/lsan_common_mac.cc)8
-rw-r--r--lib/lsan/lsan_interceptors.cpp (renamed from lib/lsan/lsan_interceptors.cc)57
-rw-r--r--lib/lsan/lsan_linux.cpp (renamed from lib/lsan/lsan_linux.cc)2
-rw-r--r--lib/lsan/lsan_mac.cpp (renamed from lib/lsan/lsan_mac.cc)4
-rw-r--r--lib/lsan/lsan_malloc_mac.cpp (renamed from lib/lsan/lsan_malloc_mac.cc)2
-rw-r--r--lib/lsan/lsan_preinit.cpp (renamed from lib/lsan/lsan_preinit.cc)2
-rw-r--r--lib/lsan/lsan_thread.cpp (renamed from lib/lsan/lsan_thread.cc)2
12 files changed, 91 insertions, 31 deletions
diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cpp
index 68697a6363e8..4ce03046ffb7 100644
--- a/lib/lsan/lsan.cc
+++ b/lib/lsan/lsan.cpp
@@ -1,4 +1,4 @@
-//=-- lsan.cc -------------------------------------------------------------===//
+//=-- lsan.cpp ------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -50,7 +50,7 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(
}
}
-using namespace __lsan; // NOLINT
+using namespace __lsan;
static void InitializeFlags() {
// Set all the default values.
@@ -89,7 +89,7 @@ static void InitializeFlags() {
static void OnStackUnwind(const SignalContext &sig, const void *,
BufferedStackTrace *stack) {
- stack->Unwind(sig.pc, sig.bp, sig.context,
+ stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
common_flags()->fast_unwind_on_fatal);
}
diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cpp
index 8b13e4c028d4..66a81ab350e5 100644
--- a/lib/lsan/lsan_allocator.cc
+++ b/lib/lsan/lsan_allocator.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_allocator.cc ---------------------------------------------------===//
+//=-- lsan_allocator.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cpp
index 7c842a152d54..9ff9f4c5d1c9 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_common.cc ------------------------------------------------------===//
+//=-- lsan_common.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -84,7 +84,7 @@ static const char kStdSuppressions[] =
void InitializeSuppressions() {
CHECK_EQ(nullptr, suppression_ctx);
- suppression_ctx = new (suppression_placeholder) // NOLINT
+ suppression_ctx = new (suppression_placeholder)
SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
suppression_ctx->ParseFromFile(flags()->suppressions);
if (&__lsan_default_suppressions)
@@ -104,7 +104,7 @@ InternalMmapVector<RootRegion> const *GetRootRegions() { return root_regions; }
void InitializeRootRegions() {
CHECK(!root_regions);
ALIGNED(64) static char placeholder[sizeof(InternalMmapVector<RootRegion>)];
- root_regions = new (placeholder) InternalMmapVector<RootRegion>(); // NOLINT
+ root_regions = new (placeholder) InternalMmapVector<RootRegion>();
}
const char *MaybeCallLsanDefaultOptions() {
@@ -162,7 +162,7 @@ void ScanRangeForPointers(uptr begin, uptr end,
uptr pp = begin;
if (pp % alignment)
pp = pp + alignment - pp % alignment;
- for (; pp + sizeof(void *) <= end; pp += alignment) { // NOLINT
+ for (; pp + sizeof(void *) <= end; pp += alignment) {
void *p = *reinterpret_cast<void **>(pp);
if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) continue;
uptr chunk = PointsIntoChunk(p);
@@ -535,7 +535,7 @@ static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) {
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(
@@ -570,11 +570,7 @@ static bool CheckForLeaks() {
EnsureMainThreadIDIsCorrect();
CheckForLeaksParam param;
param.success = false;
- LockThreadRegistry();
- LockAllocator();
- DoStopTheWorld(CheckForLeaksCallback, &param);
- UnlockAllocator();
- UnlockThreadRegistry();
+ LockStuffAndStopTheWorld(CheckForLeaksCallback, &param);
if (!param.success) {
Report("LeakSanitizer has encountered a fatal error.\n");
@@ -794,7 +790,7 @@ void EnableInThisThread() { }
}
#endif // CAN_SANITIZE_LEAKS
-using namespace __lsan; // NOLINT
+using namespace __lsan;
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h
index 58dc00faaee5..d24abe31b71b 100644
--- a/lib/lsan/lsan_common.h
+++ b/lib/lsan/lsan_common.h
@@ -129,8 +129,9 @@ struct RootRegion {
InternalMmapVector<RootRegion> const *GetRootRegions();
void ScanRootRegion(Frontier *frontier, RootRegion const &region,
uptr region_begin, uptr region_end, bool is_readable);
-// Run stoptheworld while holding any platform-specific locks.
-void DoStopTheWorld(StopTheWorldCallback callback, void* argument);
+// Run stoptheworld while holding any platform-specific locks, as well as the
+// allocator and thread registry locks.
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void* argument);
void ScanRangeForPointers(uptr begin, uptr end,
Frontier *frontier,
diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cpp
index ef4f591d88f7..ea1a4a2f569d 100644
--- a/lib/lsan/lsan_common_linux.cc
+++ b/lib/lsan/lsan_common_linux.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_common_linux.cc ------------------------------------------------===//
+//=-- lsan_common_linux.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -115,10 +115,14 @@ void HandleLeaks() {
if (common_flags()->exitcode) Die();
}
-static int DoStopTheWorldCallback(struct dl_phdr_info *info, size_t size,
- void *data) {
+static int LockStuffAndStopTheWorldCallback(struct dl_phdr_info *info,
+ size_t size, void *data) {
+ LockThreadRegistry();
+ LockAllocator();
DoStopTheWorldParam *param = reinterpret_cast<DoStopTheWorldParam *>(data);
StopTheWorld(param->callback, param->argument);
+ UnlockAllocator();
+ UnlockThreadRegistry();
return 1;
}
@@ -130,9 +134,9 @@ static int DoStopTheWorldCallback(struct dl_phdr_info *info, size_t size,
// while holding the libdl lock in the parent thread, we can safely reenter it
// in the tracer. The solution is to run stoptheworld from a dl_iterate_phdr()
// callback in the parent thread.
-void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) {
DoStopTheWorldParam param = {callback, argument};
- dl_iterate_phdr(DoStopTheWorldCallback, &param);
+ dl_iterate_phdr(LockStuffAndStopTheWorldCallback, &param);
}
} // namespace __lsan
diff --git a/lib/lsan/lsan_common_mac.cc b/lib/lsan/lsan_common_mac.cpp
index 14c2b3711994..c1804e93c11d 100644
--- a/lib/lsan/lsan_common_mac.cc
+++ b/lib/lsan/lsan_common_mac.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_common_mac.cc --------------------------------------------------===//
+//=-- lsan_common_mac.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -193,8 +193,12 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {
// causes rare race conditions.
void HandleLeaks() {}
-void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
+void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) {
+ LockThreadRegistry();
+ LockAllocator();
StopTheWorld(callback, argument);
+ UnlockAllocator();
+ UnlockThreadRegistry();
}
} // namespace __lsan
diff --git a/lib/lsan/lsan_interceptors.cc b/lib/lsan/lsan_interceptors.cpp
index 4a4c86a9dca0..f642bb807bc8 100644
--- a/lib/lsan/lsan_interceptors.cc
+++ b/lib/lsan/lsan_interceptors.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_interceptors.cc ------------------------------------------------===//
+//=-- lsan_interceptors.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -345,6 +345,55 @@ INTERCEPTOR(void, thr_exit, tid_t *state) {
#define LSAN_MAYBE_INTERCEPT_THR_EXIT
#endif
+#if SANITIZER_INTERCEPT___CXA_ATEXIT
+INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
+ void *dso_handle) {
+ __lsan::ScopedInterceptorDisabler disabler;
+ return REAL(__cxa_atexit)(func, arg, dso_handle);
+}
+#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT INTERCEPT_FUNCTION(__cxa_atexit)
+#else
+#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT
+#endif
+
+#if SANITIZER_INTERCEPT_ATEXIT
+INTERCEPTOR(int, atexit, void (*f)()) {
+ __lsan::ScopedInterceptorDisabler disabler;
+ return REAL(__cxa_atexit)((void (*)(void *a))f, 0, 0);
+}
+#define LSAN_MAYBE_INTERCEPT_ATEXIT INTERCEPT_FUNCTION(atexit)
+#else
+#define LSAN_MAYBE_INTERCEPT_ATEXIT
+#endif
+
+#if SANITIZER_INTERCEPT_PTHREAD_ATFORK
+extern "C" {
+extern int _pthread_atfork(void (*prepare)(), void (*parent)(),
+ void (*child)());
+};
+
+INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
+ void (*child)()) {
+ __lsan::ScopedInterceptorDisabler disabler;
+ // REAL(pthread_atfork) cannot be called due to symbol indirections at least
+ // on NetBSD
+ return _pthread_atfork(prepare, parent, child);
+}
+#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK INTERCEPT_FUNCTION(pthread_atfork)
+#else
+#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK
+#endif
+
+#if SANITIZER_INTERCEPT_STRERROR
+INTERCEPTOR(char *, strerror, int errnum) {
+ __lsan::ScopedInterceptorDisabler disabler;
+ return REAL(strerror)(errnum);
+}
+#define LSAN_MAYBE_INTERCEPT_STRERROR INTERCEPT_FUNCTION(strerror)
+#else
+#define LSAN_MAYBE_INTERCEPT_STRERROR
+#endif
+
struct ThreadParam {
void *(*callback)(void *arg);
void *param;
@@ -454,6 +503,12 @@ void InitializeInterceptors() {
LSAN_MAYBE_INTERCEPT__LWP_EXIT;
LSAN_MAYBE_INTERCEPT_THR_EXIT;
+ LSAN_MAYBE_INTERCEPT___CXA_ATEXIT;
+ LSAN_MAYBE_INTERCEPT_ATEXIT;
+ LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK;
+
+ LSAN_MAYBE_INTERCEPT_STRERROR;
+
#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD
if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
Report("LeakSanitizer: failed to create thread key.\n");
diff --git a/lib/lsan/lsan_linux.cc b/lib/lsan/lsan_linux.cpp
index 22d034280d7d..14a42b75d2af 100644
--- a/lib/lsan/lsan_linux.cc
+++ b/lib/lsan/lsan_linux.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_linux.cc -------------------------------------------------------===//
+//=-- lsan_linux.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lib/lsan/lsan_mac.cc b/lib/lsan/lsan_mac.cpp
index 435f41b6f8bc..b96893e2801b 100644
--- a/lib/lsan/lsan_mac.cc
+++ b/lib/lsan/lsan_mac.cpp
@@ -1,4 +1,4 @@
-//===-- lsan_mac.cc -------------------------------------------------------===//
+//===-- lsan_mac.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -90,7 +90,7 @@ extern "C" void lsan_dispatch_call_block_and_release(void *block) {
} // namespace __lsan
-using namespace __lsan; // NOLINT
+using namespace __lsan;
// Wrap |ctxt| and |func| into an lsan_block_context_t.
// The caller retains control of the allocated context.
diff --git a/lib/lsan/lsan_malloc_mac.cc b/lib/lsan/lsan_malloc_mac.cpp
index 34447b4b39fc..d03eb2e915c0 100644
--- a/lib/lsan/lsan_malloc_mac.cc
+++ b/lib/lsan/lsan_malloc_mac.cpp
@@ -1,4 +1,4 @@
-//===-- lsan_malloc_mac.cc ------------------------------------------------===//
+//===-- lsan_malloc_mac.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lib/lsan/lsan_preinit.cc b/lib/lsan/lsan_preinit.cpp
index 5d0ad89a8b02..cd94e1e8718e 100644
--- a/lib/lsan/lsan_preinit.cc
+++ b/lib/lsan/lsan_preinit.cpp
@@ -1,4 +1,4 @@
-//===-- lsan_preinit.cc ---------------------------------------------------===//
+//===-- lsan_preinit.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/lib/lsan/lsan_thread.cc b/lib/lsan/lsan_thread.cpp
index 77f6a9236dde..84e7ce61b975 100644
--- a/lib/lsan/lsan_thread.cc
+++ b/lib/lsan/lsan_thread.cpp
@@ -1,4 +1,4 @@
-//=-- lsan_thread.cc ------------------------------------------------------===//
+//=-- lsan_thread.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.