From 42fc9929ab591fe0aefdbaad529fe5087293c641 Mon Sep 17 00:00:00 2001 From: Sanjeet Karan Singh Date: Tue, 4 Apr 2023 15:17:29 -0700 Subject: [PATCH] asan_memory_profile: Fix for deadlock in memory profiler code. Calling symbolization directly from stopTheWorld was causing deadlock. For libc dep systems, symbolization uses dl_iterate_phdr, which acquire a dl write lock. It could deadlock if the lock is already acquired by one of suspended. Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D146990 --- compiler-rt/lib/asan/asan_memory_profile.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/compiler-rt/lib/asan/asan_memory_profile.cpp b/compiler-rt/lib/asan/asan_memory_profile.cpp index 6c2b740..3396fc2 100644 --- a/compiler-rt/lib/asan/asan_memory_profile.cpp +++ b/compiler-rt/lib/asan/asan_memory_profile.cpp @@ -11,12 +11,11 @@ // This file implements __sanitizer_print_memory_profile. //===----------------------------------------------------------------------===// +#include "asan/asan_allocator.h" +#include "lsan/lsan_common.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_stacktrace.h" -#include "sanitizer_common/sanitizer_stoptheworld.h" -#include "lsan/lsan_common.h" -#include "asan/asan_allocator.h" #if CAN_SANITIZE_LEAKS @@ -100,19 +99,16 @@ static void ChunkCallback(uptr chunk, void *arg) { FindHeapChunkByAllocBeg(chunk)); } -static void MemoryProfileCB(const SuspendedThreadsList &suspended_threads_list, - void *argument) { +static void MemoryProfileCB(uptr top_percent, uptr max_number_of_contexts) { HeapProfile hp; + __lsan::LockAllocator(); __lsan::ForEachChunk(ChunkCallback, &hp); - uptr *Arg = reinterpret_cast(argument); - hp.Print(Arg[0], Arg[1]); + __lsan::UnlockAllocator(); + hp.Print(top_percent, max_number_of_contexts); if (Verbosity()) __asan_print_accumulated_stats(); } - -#if SANITIZER_LINUX || SANITIZER_NETBSD -#endif } // namespace __asan #endif // CAN_SANITIZE_LEAKS @@ -122,10 +118,7 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_print_memory_profile(uptr top_percent, uptr max_number_of_contexts) { #if CAN_SANITIZE_LEAKS - uptr Arg[2]; - Arg[0] = top_percent; - Arg[1] = max_number_of_contexts; - __sanitizer::StopTheWorld(__asan::MemoryProfileCB, Arg); + __asan::MemoryProfileCB(top_percent, max_number_of_contexts); #endif // CAN_SANITIZE_LEAKS } } // extern "C" -- 2.7.4