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.
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)
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
#include <vector>
-#include "debug_disable.h"
#include "MapData.h"
// Format of /proc/<PID>/maps:
}
bool MapData::Initialize() {
- ScopedDisableDebugCalls disable;
-
FILE* fp = fopen("/proc/self/maps", "re");
if (fp == nullptr) {
return false;
}
MapData::~MapData() {
- ScopedDisableDebugCalls disable;
-
for (auto* entry : entries_) {
delete entry;
}
#include <unwind.h>
#include "backtrace.h"
-#include "debug_disable.h"
#include "debug_log.h"
#include "MapData.h"
}
void backtrace_startup() {
- ScopedDisableDebugCalls disable;
-
g_map_data = MapData::Create();
if (g_map_data) {
_Unwind_Backtrace(find_current_map, nullptr);
}
void backtrace_shutdown() {
- ScopedDisableDebugCalls disable;
-
delete g_map_data;
g_map_data = nullptr;
}
}
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;
if (soname == nullptr) {
soname = "<unknown>";
}
+ 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());
}
#include <stdint.h>
#include <sys/cdefs.h>
+#include <string>
+
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
__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__ )
g_debug->track->DisplayLeaks(*g_debug);
}
- backtrace_shutdown();
-
DebugDisableSet(true);
+ backtrace_shutdown();
+
delete g_debug;
g_debug = nullptr;
__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.
//