summaryrefslogtreecommitdiff
path: root/libc/malloc_debug/malloc_debug.cpp
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2016-02-02 11:57:54 -0800
committerColin Cross <ccross@android.com>2016-02-18 16:09:16 -0800
commit2d4721c0c57fe2f7c1e1b40df4763a561b3cf856 (patch)
tree256b5519e32df5b56b6bc6a343f5ff50d16ddea0 /libc/malloc_debug/malloc_debug.cpp
parent869691c6f7691dd5bf343617aa185c32e0d3d160 (diff)
Export malloc_backtrace
Change-Id: Ic1adb4dfd86b9ca698443a36263a3df2c91edda3
Diffstat (limited to 'libc/malloc_debug/malloc_debug.cpp')
-rw-r--r--libc/malloc_debug/malloc_debug.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 5b6e415cf..e079c7e66 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -67,6 +67,7 @@ void debug_finalize();
void debug_get_malloc_leak_info(
uint8_t** info, size_t* overall_size, size_t* info_size, size_t* total_memory,
size_t* backtrace_size);
+ssize_t debug_malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count);
void debug_free_malloc_leak_info(uint8_t* info);
size_t debug_malloc_usable_size(void* pointer);
void* debug_malloc(size_t size);
@@ -163,6 +164,7 @@ static void* InitHeader(Header* header, void* orig_pointer, size_t size) {
if (g_debug->config().options & BACKTRACE) {
BacktraceHeader* back_header = g_debug->GetAllocBacktrace(header);
if (g_debug->backtrace->enabled()) {
+ ScopedDisableDebugCalls disable;
back_header->num_frames = backtrace_get(
&back_header->frames[0], g_debug->config().backtrace_frames);
backtrace_found = back_header->num_frames > 0;
@@ -616,6 +618,39 @@ void debug_malloc_enable() {
g_dispatch->malloc_enable();
}
+ssize_t debug_malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count) {
+ if (DebugCallsDisabled() || pointer == nullptr) {
+ return 0;
+ }
+
+ if (g_debug->need_header()) {
+ Header* header;
+ if (g_debug->config().options & TRACK_ALLOCS) {
+ header = g_debug->GetHeader(pointer);
+ if (!g_debug->track->Contains(header)) {
+ return 0;
+ }
+ } else {
+ header = reinterpret_cast<Header*>(pointer);
+ }
+ if (header->tag != DEBUG_TAG) {
+ return 0;
+ }
+ if (g_debug->config().options & BACKTRACE) {
+ BacktraceHeader* back_header = g_debug->GetAllocBacktrace(header);
+ if (back_header->num_frames > 0) {
+ if (frame_count > back_header->num_frames) {
+ frame_count = back_header->num_frames;
+ }
+ memcpy(frames, &back_header->frames[0], frame_count * sizeof(uintptr_t));
+ return frame_count;
+ }
+ }
+ }
+
+ return 0;
+}
+
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
void* debug_pvalloc(size_t bytes) {
if (DebugCallsDisabled()) {