Change heap dump format slightly.
Bump the version from v1.1 to v1.2 and add a build fingerprint line.
Update the heap dump documentation to match the new format and reflect
what made it in P and what made it in Q.
Update the unit tests for this change.
Add -O0 to unit test code to make it easier to debug.
Add an external function that can be used by the framework code
so that there is only one way to dump the heap.
Bug: 110095681
Test: Ran unit tests.
Test: Did a dump of a real process and verified fingerprint.
Test: Did a dump of a process without malloc debug enabled.
Change-Id: I769a476cbeaf4c85c5d75bd6d6385f0e3add948c
Merged-In: I769a476cbeaf4c85c5d75bd6d6385f0e3add948c
(cherry picked from commit c84a2a2601a4112ca6e43a33defb989c1da8c2f4)
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index a4ff5d4..0cb4cca 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -139,5 +139,6 @@
"-Wall",
"-Werror",
"-Wno-error=format-zero-length",
+ "-O0",
],
}
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index c427d5f..c4ee722 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -161,7 +161,7 @@
when the program exits will be backtrace\_dump\_prefix.**PID**.exit.txt.
### backtrace\_full
-As of P, any time that a backtrace is gathered, a different algorithm is used
+As of Q, any time that a backtrace is gathered, a different algorithm is used
that is extra thorough and can unwind through Java frames. This will run
slower than the normal backtracing function.
@@ -495,15 +495,32 @@
The map data is simply the output of /proc/PID/maps. This data can be used to
decode the frames in the backtraces.
-As of Android P, there is a new version of this file. The new header is:
+There are now multiple versions of the file:
+
+Android P produces version v1.1 of the heap dump.
Android Native Heap Dump v1.1
-The new version no longer 0 pads the backtrace addresses. In v1.0:
+The only difference between v1.0 and v1.1 is that the NUM\_ALLOCATIONS
+value is always accurate in v1.1. A previous version of malloc debug set
+NUM\_ALLOCATIONS to an incorrect value. For heap dump v1.0, the
+NUM\_ALLOCATIONS value should be treated as always 1 no matter what is
+actually present.
+
+Android Q introduces v1.2 of the heap dump. The new header looks like this:
+
+ Android Native Heap Dump v1.2
+
+ Build fingerprint: 'google/taimen/taimen:8.1.0/OPM2.171026.006.C1/4769658:user/release-keys'
+
+The new line fingerprint line is the contents of the ro.build.fingerprint
+property.
+
+The new version no longer 0 pads the backtrace addresses. In v1.0/v1.1:
z 0 sz 400 num 1 bt 0000a230 0000b500
-While v1.1:
+While v1.2:
z 0 sz 400 num 1 bt a230 b500
diff --git a/libc/malloc_debug/exported32.map b/libc/malloc_debug/exported32.map
index 78a6990..2f590d0 100644
--- a/libc/malloc_debug/exported32.map
+++ b/libc/malloc_debug/exported32.map
@@ -21,6 +21,7 @@
debug_pvalloc;
debug_realloc;
debug_valloc;
+ debug_write_malloc_leak_info;
local:
*;
diff --git a/libc/malloc_debug/exported64.map b/libc/malloc_debug/exported64.map
index 2bfc38b..08d36a5 100644
--- a/libc/malloc_debug/exported64.map
+++ b/libc/malloc_debug/exported64.map
@@ -19,6 +19,7 @@
debug_memalign;
debug_posix_memalign;
debug_realloc;
+ debug_write_malloc_leak_info;
local:
*;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 836c33b..1e7086c 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -38,6 +38,7 @@
#include <vector>
#include <android-base/file.h>
+#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <private/bionic_malloc_dispatch.h>
@@ -69,9 +70,10 @@
bool debug_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child,
const char* options);
void debug_finalize();
-bool debug_dump_heap(const char* file_name);
+void debug_dump_heap(const char* file_name);
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);
+bool debug_write_malloc_leak_info(FILE* fp);
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);
@@ -813,28 +815,11 @@
static std::mutex g_dump_lock;
-bool debug_dump_heap(const char* file_name) {
- ScopedDisableDebugCalls disable;
+static void write_dump(FILE* fp) {
+ fprintf(fp, "Android Native Heap Dump v1.2\n\n");
- std::lock_guard<std::mutex> guard(g_dump_lock);
-
- FILE* fp = fopen(file_name, "w+e");
- if (fp == nullptr) {
- error_log("Unable to create file: %s", file_name);
- return false;
- }
- error_log("Dumping to file: %s\n", file_name);
-
- if (!(g_debug->config().options() & BACKTRACE)) {
- fprintf(fp, "Native heap dump not available. To enable, run these commands (requires root):\n");
- fprintf(fp, "# adb shell stop\n");
- fprintf(fp, "# adb shell setprop libc.debug.malloc.options backtrace\n");
- fprintf(fp, "# adb shell start\n");
- fclose(fp);
- return false;
- }
-
- fprintf(fp, "Android Native Heap Dump v1.1\n\n");
+ std::string fingerprint = android::base::GetProperty("ro.build.fingerprint", "unknown");
+ fprintf(fp, "Build fingerprint: '%s'\n\n", fingerprint.c_str());
PointerData::DumpLiveToFile(fp);
@@ -846,6 +831,33 @@
fprintf(fp, "%s", content.c_str());
}
fprintf(fp, "END\n");
- fclose(fp);
+}
+
+bool debug_write_malloc_leak_info(FILE* fp) {
+ ScopedDisableDebugCalls disable;
+
+ std::lock_guard<std::mutex> guard(g_dump_lock);
+
+ if (!(g_debug->config().options() & BACKTRACE)) {
+ return false;
+ }
+
+ write_dump(fp);
return true;
}
+
+void debug_dump_heap(const char* file_name) {
+ ScopedDisableDebugCalls disable;
+
+ std::lock_guard<std::mutex> guard(g_dump_lock);
+
+ FILE* fp = fopen(file_name, "w+e");
+ if (fp == nullptr) {
+ error_log("Unable to create file: %s", file_name);
+ return;
+ }
+
+ error_log("Dumping to file: %s\n", file_name);
+ write_dump(fp);
+ fclose(fp);
+}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 0663f6a..cd6d2c2 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -1250,10 +1250,15 @@
continue;
}
}
- if (line == "MAPS") {
- skip_map_data = true;
+
+ if (android::base::StartsWith(line, "Build fingerprint:")) {
+ sanitized += "Build fingerprint: ''\n";
+ } else {
+ if (line == "MAPS") {
+ skip_map_data = true;
+ }
+ sanitized += line + '\n';
}
- sanitized += line + '\n';
}
return sanitized;
}
@@ -1312,7 +1317,9 @@
std::string sanitized(SanitizeHeapData(actual));
std::string expected =
-R"(Android Native Heap Dump v1.1
+R"(Android Native Heap Dump v1.2
+
+Build fingerprint: ''
Total memory: 405
Allocation records: 6
@@ -1377,7 +1384,9 @@
std::string sanitized(SanitizeHeapData(actual));
std::string expected =
-R"(Android Native Heap Dump v1.1
+R"(Android Native Heap Dump v1.2
+
+Build fingerprint: ''
Total memory: 1200
Allocation records: 3
@@ -1426,7 +1435,9 @@
std::string sanitized(SanitizeHeapData(actual));
std::string expected =
-R"(Android Native Heap Dump v1.1
+R"(Android Native Heap Dump v1.2
+
+Build fingerprint: ''
Total memory: 1000
Allocation records: 2
@@ -1482,7 +1493,9 @@
std::string sanitized(SanitizeHeapData(actual));
std::string expected =
-R"(Android Native Heap Dump v1.1
+R"(Android Native Heap Dump v1.2
+
+Build fingerprint: ''
Total memory: 1200
Allocation records: 3