OSDN Git Service

Export malloc_backtrace
authorColin Cross <ccross@android.com>
Tue, 2 Feb 2016 19:57:54 +0000 (11:57 -0800)
committerChristopher Ferris <cferris@google.com>
Tue, 23 Feb 2016 23:55:44 +0000 (15:55 -0800)
Bug: 27208635
(cherry picked from commit 2d4721c0c57fe2f7c1e1b40df4763a561b3cf856)

Change-Id: Ida926cabb706dfd962b692ba1775da332f68488f

14 files changed:
libc/bionic/malloc_common.cpp
libc/libc.arm.brillo.map
libc/libc.arm.map
libc/libc.arm64.map
libc/libc.map.txt
libc/libc.mips.brillo.map
libc/libc.mips.map
libc/libc.mips64.map
libc/libc.x86.brillo.map
libc/libc.x86.map
libc/libc.x86_64.map
libc/malloc_debug/exported32.map
libc/malloc_debug/exported64.map
libc/malloc_debug/malloc_debug.cpp

index b991b9a..863b07c 100644 (file)
@@ -183,6 +183,7 @@ static void* libc_malloc_impl_handle = nullptr;
 static void (*g_debug_finalize_func)();
 static void (*g_debug_get_malloc_leak_info_func)(uint8_t**, size_t*, size_t*, size_t*, size_t*);
 static void (*g_debug_free_malloc_leak_info_func)(uint8_t*);
+static ssize_t (*g_debug_malloc_backtrace_func)(void*, uintptr_t*, size_t);
 
 // =============================================================================
 // Log functions
@@ -369,6 +370,15 @@ static void malloc_init_impl(libc_globals* globals) {
   }
   g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(sym);
 
+  sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
+  if (sym == nullptr) {
+    error_log("%s: debug_malloc_backtrace routine not found in %s", getprogname(),
+              DEBUG_SHARED_LIB);
+    dlclose(malloc_impl_handle);
+    return;
+  }
+  g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(void*, uintptr_t*, size_t)>(sym);
+
   if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild)) {
     dlclose(malloc_impl_handle);
     return;
@@ -436,3 +446,16 @@ extern "C" void malloc_enable() {
   }
   return Malloc(malloc_enable)();
 }
+
+#ifndef LIBC_STATIC
+extern "C" ssize_t malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_count) {
+  if (g_debug_malloc_backtrace_func == nullptr) {
+    return 0;
+  }
+  return g_debug_malloc_backtrace_func(pointer, frames, frame_count);
+}
+#else
+extern "C" ssize_t malloc_backtrace(void*, uintptr_t*, size_t) {
+  return 0;
+}
+#endif
index 1da85ea..2c0ab15 100644 (file)
@@ -627,6 +627,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index bad3fec..c22535d 100644 (file)
@@ -627,6 +627,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index c7aca4f..63c82e5 100644 (file)
@@ -552,6 +552,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index 1f4da93..c000fb1 100644 (file)
@@ -630,6 +630,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index 3562ebf..8e5fdf4 100644 (file)
@@ -625,6 +625,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index 1f7b9aa..d30ead8 100644 (file)
@@ -625,6 +625,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index c7aca4f..63c82e5 100644 (file)
@@ -552,6 +552,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index c57a072..7ac0976 100644 (file)
@@ -624,6 +624,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index 56d6609..11fb710 100644 (file)
@@ -624,6 +624,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index c7aca4f..63c82e5 100644 (file)
@@ -552,6 +552,7 @@ LIBC {
     madvise;
     mallinfo;
     malloc;
+    malloc_backtrace;
     malloc_disable;
     malloc_enable;
     malloc_iterate;
index 8f994f1..a985ef9 100644 (file)
@@ -9,6 +9,7 @@ LIBC_MALLOC_DEBUG {
     debug_iterate;
     debug_mallinfo;
     debug_malloc;
+    debug_malloc_backtrace;
     debug_malloc_disable;
     debug_malloc_enable;
     debug_malloc_usable_size;
index 8c47449..1a6b30f 100644 (file)
@@ -9,6 +9,7 @@ LIBC_MALLOC_DEBUG {
     debug_iterate;
     debug_mallinfo;
     debug_malloc;
+    debug_malloc_backtrace;
     debug_malloc_disable;
     debug_malloc_enable;
     debug_malloc_usable_size;
index 5b6e415..e079c7e 100644 (file)
@@ -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()) {