diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp index 344f9a783..864dfb64e 100644 --- a/libc/malloc_debug/Android.bp +++ b/libc/malloc_debug/Android.bp @@ -181,7 +181,6 @@ cc_test { shared_libs: [ "libbase", - "libbacktrace", "liblog", "libunwindstack", ], diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp index eaa0eb7c7..d062086f5 100644 --- a/libc/malloc_debug/PointerData.cpp +++ b/libc/malloc_debug/PointerData.cpp @@ -149,14 +149,14 @@ size_t PointerData::AddBacktrace(size_t num_frames) { if (num_frames == 0) { return kBacktraceEmptyIndex; } + frames.resize(num_frames); } - FrameKeyType key{.num_frames = num_frames, .frames = frames.data()}; + FrameKeyType key{.num_frames = frames.size(), .frames = frames.data()}; size_t hash_index; std::lock_guard frame_guard(frame_mutex_); auto entry = key_to_index_.find(key); if (entry == key_to_index_.end()) { - frames.resize(num_frames); hash_index = cur_hash_index_++; key.frames = frames.data(); key_to_index_.emplace(key, hash_index); diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp index f6c3e69e0..c892a39da 100644 --- a/libc/malloc_debug/UnwindBacktrace.cpp +++ b/libc/malloc_debug/UnwindBacktrace.cpp @@ -36,11 +36,7 @@ #include #include -#include -#include -#include -#include -#include +#include #include #include "UnwindBacktrace.h" @@ -54,51 +50,22 @@ extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*); -static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT; - -static unwindstack::LocalUpdatableMaps* g_maps; -static std::shared_ptr g_process_memory; -#if defined(__LP64__) -static std::vector g_skip_libraries{"/system/lib64/libunwindstack.so", - "/system/lib64/libc_malloc_debug.so"}; -#else -static std::vector g_skip_libraries{"/system/lib/libunwindstack.so", - "/system/lib/libc_malloc_debug.so"}; -#endif - -static void Setup() { - g_maps = new unwindstack::LocalUpdatableMaps; - if (!g_maps->Parse()) { - delete g_maps; - g_maps = nullptr; - } - - g_process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid()); -} - bool Unwind(std::vector* frames, std::vector* frame_info, size_t max_frames) { - pthread_once(&g_setup_once, Setup); - - if (g_maps == nullptr) { - return false; - } - - std::unique_ptr regs(unwindstack::Regs::CreateFromLocal()); - unwindstack::RegsGetLocal(regs.get()); - unwindstack::Unwinder unwinder(max_frames, g_maps, regs.get(), g_process_memory); - unwinder.Unwind(&g_skip_libraries); - if (unwinder.NumFrames() == 0) { + [[clang::no_destroy]] static unwindstack::AndroidLocalUnwinder unwinder( + std::vector{"libc_malloc_debug.so"}); + unwindstack::AndroidUnwinderData data(max_frames); + if (!unwinder.Unwind(data)) { frames->clear(); frame_info->clear(); return false; } - *frame_info = unwinder.ConsumeFrames(); - frames->resize(frame_info->size()); - for (size_t i = 0; i < frame_info->size(); i++) { - frames->at(i) = frame_info->at(i).pc; + frames->resize(data.frames.size()); + for (const auto& frame : data.frames) { + frames->at(frame.num) = frame.pc; } + *frame_info = std::move(data.frames); return true; } diff --git a/libc/malloc_debug/UnwindBacktrace.h b/libc/malloc_debug/UnwindBacktrace.h index 7f8990716..091865eec 100644 --- a/libc/malloc_debug/UnwindBacktrace.h +++ b/libc/malloc_debug/UnwindBacktrace.h @@ -30,10 +30,8 @@ #include -#include #include -#include #include bool Unwind(std::vector* frames, std::vector* info, diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp index 92679e48b..aee2572ba 100644 --- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp +++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp @@ -52,8 +52,7 @@ #include #include -#include -#include +#include #include #include @@ -452,12 +451,19 @@ class MallocDebugSystemTest : public ::testing::Test { static constexpr size_t kMaxRetries = 3; }; -TEST(MallocTests, DISABLED_smoke) {} +TEST(MallocTests, DISABLED_smoke) { + void* ptr = malloc(128); + free(ptr); +} TEST_F(MallocDebugSystemTest, smoke) { Exec("MallocTests.DISABLED_smoke", "verbose backtrace"); } +TEST_F(MallocDebugSystemTest, backtrace_full_smoke) { + Exec("MallocTests.DISABLED_smoke", "verbose backtrace backtrace_full"); +} + static void SetAllocationLimit() { // Set to a large value, this is only to enable the limit code and // verify that malloc debug is still called properly. @@ -763,13 +769,14 @@ TEST(MallocTests, DISABLED_malloc_and_backtrace_deadlock) { } static constexpr size_t kNumUnwinds = 1000; + unwindstack::AndroidLocalUnwinder unwinder; for (size_t i = 0; i < kNumUnwinds; i++) { - std::unique_ptr backtrace(Backtrace::Create(getpid(), tid)); // Only verify that there is at least one frame in the unwind. // This is not a test of the unwinder and clang for arm seems to // produces an increasing number of code that does not have unwind // information. - ASSERT_TRUE(backtrace->Unwind(0)) << "Failed on unwind " << i; + unwindstack::AndroidUnwinderData data; + ASSERT_TRUE(unwinder.Unwind(data)) << "Failed on unwind " << i; } running = false; thread.join();