diff options
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.h | 5 | ||||
-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, ¶m); - UnlockAllocator(); - UnlockThreadRegistry(); + LockStuffAndStopTheWorld(CheckForLeaksCallback, ¶m); 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 ®ion, 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, ¶m); + dl_iterate_phdr(LockStuffAndStopTheWorldCallback, ¶m); } } // 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. |