From 6deb3042df87f8569fb430dbf5f140f6a694ddfd Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 5 Feb 2016 16:17:39 -0800 Subject: [PATCH] Add backtrace_string and export to libmemunreachable Add backtrace_string to convert a malloc_debug backtrace to a string. Also move the backtrace functions to libc_malloc_debug_backtrace so that libmemunreachable can reuse them. Bug: 27208635 (cherry picked from commit 2c75991359df165ca7cc7a6213fb227c0b5ed87c) Change-Id: Ia93aaf010fbce1ace058439427066ea2dfd8bd13 --- libc/bionic/libc_logging.cpp | 2 +- libc/malloc_debug/Android.mk | 41 ++++++++++++++++++++++++++++++++++---- libc/malloc_debug/MapData.cpp | 5 ----- libc/malloc_debug/backtrace.cpp | 27 ++++++++++++++----------- libc/malloc_debug/backtrace.h | 3 +++ libc/malloc_debug/debug_log.h | 2 ++ libc/malloc_debug/malloc_debug.cpp | 4 ++-- libc/private/libc_logging.h | 2 ++ 8 files changed, 62 insertions(+), 24 deletions(-) diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp index 67bb0524e..fffaea8e4 100644 --- a/libc/bionic/libc_logging.cpp +++ b/libc/bionic/libc_logging.cpp @@ -548,7 +548,7 @@ struct log_time { // Wire format uint32_t tv_nsec; }; -static int __libc_write_log(int priority, const char* tag, const char* msg) { +int __libc_write_log(int priority, const char* tag, const char* msg) { int main_log_fd = __libc_open_log_socket(); if (main_log_fd == -1) { // Try stderr instead. diff --git a/libc/malloc_debug/Android.mk b/libc/malloc_debug/Android.mk index 3eb079081..fb366430b 100644 --- a/libc/malloc_debug/Android.mk +++ b/libc/malloc_debug/Android.mk @@ -11,6 +11,38 @@ libc_malloc_debug_src_files := \ TrackData.cpp \ # ============================================================== +# libc_malloc_debug_backtrace.a +# ============================================================== +# Used by libmemunreachable +include $(CLEAR_VARS) + +LOCAL_MODULE := libc_malloc_debug_backtrace + +LOCAL_SRC_FILES := \ + backtrace.cpp \ + MapData.cpp \ + +LOCAL_CXX_STL := libc++_static + +LOCAL_STATIC_LIBRARIES += \ + libc_logging \ + +LOCAL_C_INCLUDES += bionic/libc +LOCAL_EXPORT_C_INCLUDE_DIRS += $(LOCAL_PATH) + +LOCAL_SANITIZE := never +LOCAL_NATIVE_COVERAGE := false + +# -Wno-error=format-zero-length needed for gcc to compile. +LOCAL_CFLAGS := \ + -Wall \ + -Werror \ + -fno-stack-protector \ + -Wno-error=format-zero-length \ + +include $(BUILD_STATIC_LIBRARY) + +# ============================================================== # libc_malloc_debug.so # ============================================================== include $(CLEAR_VARS) @@ -19,16 +51,17 @@ LOCAL_MODULE := libc_malloc_debug LOCAL_SRC_FILES := \ $(libc_malloc_debug_src_files) \ - backtrace.cpp \ - MapData.cpp \ -LOCAL_CXX_STL := none +LOCAL_CXX_STL := libc++_static # Only need this for arm since libc++ uses its own unwind code that # doesn't mix with the other default unwind code. LOCAL_STATIC_LIBRARIES_arm := libunwind_llvm -LOCAL_STATIC_LIBRARIES += libc++abi libc++_static libc_logging +LOCAL_STATIC_LIBRARIES += \ + libc_malloc_debug_backtrace \ + libc_logging \ + LOCAL_LDFLAGS_32 := -Wl,--version-script,$(LOCAL_PATH)/exported32.map LOCAL_LDFLAGS_64 := -Wl,--version-script,$(LOCAL_PATH)/exported64.map LOCAL_ALLOW_UNDEFINED_SYMBOLS := true diff --git a/libc/malloc_debug/MapData.cpp b/libc/malloc_debug/MapData.cpp index ce2b99995..c38362b67 100644 --- a/libc/malloc_debug/MapData.cpp +++ b/libc/malloc_debug/MapData.cpp @@ -36,7 +36,6 @@ #include -#include "debug_disable.h" #include "MapData.h" // Format of /proc//maps: @@ -112,8 +111,6 @@ static void read_loadbase(MapEntry* entry) { } bool MapData::Initialize() { - ScopedDisableDebugCalls disable; - FILE* fp = fopen("/proc/self/maps", "re"); if (fp == nullptr) { return false; @@ -141,8 +138,6 @@ MapData* MapData::Create() { } MapData::~MapData() { - ScopedDisableDebugCalls disable; - for (auto* entry : entries_) { delete entry; } diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp index 8549dc49b..716e6726a 100644 --- a/libc/malloc_debug/backtrace.cpp +++ b/libc/malloc_debug/backtrace.cpp @@ -37,7 +37,6 @@ #include #include "backtrace.h" -#include "debug_disable.h" #include "debug_log.h" #include "MapData.h" @@ -65,8 +64,6 @@ static _Unwind_Reason_Code find_current_map(__unwind_context* context, void*) { } void backtrace_startup() { - ScopedDisableDebugCalls disable; - g_map_data = MapData::Create(); if (g_map_data) { _Unwind_Backtrace(find_current_map, nullptr); @@ -74,8 +71,6 @@ void backtrace_startup() { } void backtrace_shutdown() { - ScopedDisableDebugCalls disable; - delete g_map_data; g_map_data = nullptr; } @@ -136,15 +131,13 @@ static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg) } size_t backtrace_get(uintptr_t* frames, size_t frame_count) { - ScopedDisableDebugCalls disable; - stack_crawl_state_t state(frames, frame_count); _Unwind_Backtrace(trace_function, &state); return state.cur_frame; } -void backtrace_log(const uintptr_t* frames, size_t frame_count) { - ScopedDisableDebugCalls disable; +std::string backtrace_string(const uintptr_t* frames, size_t frame_count) { + std::string str; for (size_t frame_num = 0; frame_num < frame_count; frame_num++) { uintptr_t offset = 0; @@ -165,15 +158,25 @@ void backtrace_log(const uintptr_t* frames, size_t frame_count) { if (soname == nullptr) { soname = ""; } + char buf[1024]; if (symbol != nullptr) { char* demangled_symbol = __cxa_demangle(symbol, nullptr, nullptr, nullptr); const char* best_name = (demangled_symbol != nullptr) ? demangled_symbol : symbol; - error_log(" #%02zd pc %" PAD_PTR " %s (%s+%" PRIuPTR ")", - frame_num, rel_pc, soname, best_name, frames[frame_num] - offset); + __libc_format_buffer(buf, sizeof(buf), + " #%02zd pc %" PAD_PTR " %s (%s+%" PRIuPTR ")\n", frame_num, + rel_pc, soname, best_name, frames[frame_num] - offset); free(demangled_symbol); } else { - error_log(" #%02zd pc %" PAD_PTR " %s", frame_num, rel_pc, soname); + __libc_format_buffer(buf, sizeof(buf), + " #%02zd pc %" PAD_PTR " %s\n", frame_num, rel_pc, soname); } + str += buf; } + + return str; +} + +void backtrace_log(const uintptr_t* frames, size_t frame_count) { + error_log_string(backtrace_string(frames, frame_count).c_str()); } diff --git a/libc/malloc_debug/backtrace.h b/libc/malloc_debug/backtrace.h index 9e010095f..f5708737d 100644 --- a/libc/malloc_debug/backtrace.h +++ b/libc/malloc_debug/backtrace.h @@ -32,9 +32,12 @@ #include #include +#include + void backtrace_startup(); void backtrace_shutdown(); size_t backtrace_get(uintptr_t* frames, size_t frame_count); void backtrace_log(const uintptr_t* frames, size_t frame_count); +std::string backtrace_string(const uintptr_t* frames, size_t frame_count); #endif // MALLOC_DEBUG_BACKTRACE_H diff --git a/libc/malloc_debug/debug_log.h b/libc/malloc_debug/debug_log.h index 67f584da6..4df040805 100644 --- a/libc/malloc_debug/debug_log.h +++ b/libc/malloc_debug/debug_log.h @@ -38,6 +38,8 @@ __libc_format_log(ANDROID_LOG_DEBUG, "malloc_debug", (format), ##__VA_ARGS__ ) #define error_log(format, ...) \ __libc_format_log(ANDROID_LOG_ERROR, "malloc_debug", (format), ##__VA_ARGS__ ) +#define error_log_string(str) \ + __libc_write_log(ANDROID_LOG_ERROR, "malloc_debug", (str)) #define info_log(format, ...) \ __libc_format_log(ANDROID_LOG_INFO, "malloc_debug", (format), ##__VA_ARGS__ ) diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp index e079c7e66..aa6f5f747 100644 --- a/libc/malloc_debug/malloc_debug.cpp +++ b/libc/malloc_debug/malloc_debug.cpp @@ -223,10 +223,10 @@ void debug_finalize() { g_debug->track->DisplayLeaks(*g_debug); } - backtrace_shutdown(); - DebugDisableSet(true); + backtrace_shutdown(); + delete g_debug; g_debug = nullptr; diff --git a/libc/private/libc_logging.h b/libc/private/libc_logging.h index da2192bba..e389565f5 100644 --- a/libc/private/libc_logging.h +++ b/libc/private/libc_logging.h @@ -101,6 +101,8 @@ __LIBC_HIDDEN__ int __libc_format_log(int priority, const char* tag, const char* __LIBC_HIDDEN__ int __libc_format_log_va_list(int priority, const char* tag, const char* format, va_list ap); +__LIBC_HIDDEN__ int __libc_write_log(int priority, const char* tag, const char* msg); + // // Event logging. // -- 2.11.0