summaryrefslogtreecommitdiff
path: root/libc/malloc_debug/malloc_debug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libc/malloc_debug/malloc_debug.cpp')
-rw-r--r--libc/malloc_debug/malloc_debug.cpp53
1 files changed, 32 insertions, 21 deletions
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d2679ca4c..3da694c75 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -97,8 +97,8 @@ struct mallinfo debug_mallinfo();
int debug_mallopt(int param, int value);
int debug_malloc_info(int options, FILE* fp);
int debug_posix_memalign(void** memptr, size_t alignment, size_t size);
-int debug_iterate(uintptr_t base, size_t size,
- void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
+int debug_malloc_iterate(uintptr_t base, size_t size,
+ void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
void debug_malloc_disable();
void debug_malloc_enable();
@@ -808,16 +808,23 @@ int debug_malloc_info(int options, FILE* fp) {
if (DebugCallsDisabled() || !g_debug->TrackPointers()) {
return g_dispatch->malloc_info(options, fp);
}
+
+ // Make sure any pending output is written to the file.
+ fflush(fp);
+
ScopedConcurrentLock lock;
ScopedDisableDebugCalls disable;
- MallocXmlElem root(fp, "malloc", "version=\"debug-malloc-1\"");
+ // Avoid any issues where allocations are made that will be freed
+ // in the fclose.
+ int fd = fileno(fp);
+ MallocXmlElem root(fd, "malloc", "version=\"debug-malloc-1\"");
std::vector<ListInfoType> list;
PointerData::GetAllocList(&list);
size_t alloc_num = 0;
for (size_t i = 0; i < list.size(); i++) {
- MallocXmlElem alloc(fp, "allocation", "nr=\"%zu\"", alloc_num);
+ MallocXmlElem alloc(fd, "allocation", "nr=\"%zu\"", alloc_num);
size_t total = 1;
size_t size = list[i].size;
@@ -825,8 +832,8 @@ int debug_malloc_info(int options, FILE* fp) {
i++;
total++;
}
- MallocXmlElem(fp, "size").Contents("%zu", list[i].size);
- MallocXmlElem(fp, "total").Contents("%zu", total);
+ MallocXmlElem(fd, "size").Contents("%zu", list[i].size);
+ MallocXmlElem(fd, "total").Contents("%zu", total);
alloc_num++;
}
return 0;
@@ -857,7 +864,7 @@ int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
return (*memptr != nullptr) ? 0 : ENOMEM;
}
-int debug_iterate(uintptr_t base, size_t size, void (*callback)(uintptr_t, size_t, void*),
+int debug_malloc_iterate(uintptr_t base, size_t size, void (*callback)(uintptr_t, size_t, void*),
void* arg) {
ScopedConcurrentLock lock;
if (g_debug->TrackPointers()) {
@@ -870,7 +877,7 @@ int debug_iterate(uintptr_t base, size_t size, void (*callback)(uintptr_t, size_
// An option that adds a header will add pointer tracking, so no need to
// check if headers are enabled.
- return g_dispatch->iterate(base, size, callback, arg);
+ return g_dispatch->malloc_iterate(base, size, callback, arg);
}
void debug_malloc_disable() {
@@ -928,25 +935,28 @@ void* debug_valloc(size_t size) {
static std::mutex g_dump_lock;
-static void write_dump(FILE* fp) {
- fprintf(fp, "Android Native Heap Dump v1.2\n\n");
+static void write_dump(int fd) {
+ dprintf(fd, "Android Native Heap Dump v1.2\n\n");
std::string fingerprint = android::base::GetProperty("ro.build.fingerprint", "unknown");
- fprintf(fp, "Build fingerprint: '%s'\n\n", fingerprint.c_str());
+ dprintf(fd, "Build fingerprint: '%s'\n\n", fingerprint.c_str());
- PointerData::DumpLiveToFile(fp);
+ PointerData::DumpLiveToFile(fd);
- fprintf(fp, "MAPS\n");
+ dprintf(fd, "MAPS\n");
std::string content;
if (!android::base::ReadFileToString("/proc/self/maps", &content)) {
- fprintf(fp, "Could not open /proc/self/maps\n");
+ dprintf(fd, "Could not open /proc/self/maps\n");
} else {
- fprintf(fp, "%s", content.c_str());
+ dprintf(fd, "%s", content.c_str());
}
- fprintf(fp, "END\n");
+ dprintf(fd, "END\n");
}
bool debug_write_malloc_leak_info(FILE* fp) {
+ // Make sure any pending output is written to the file.
+ fflush(fp);
+
ScopedConcurrentLock lock;
ScopedDisableDebugCalls disable;
@@ -956,7 +966,8 @@ bool debug_write_malloc_leak_info(FILE* fp) {
return false;
}
- write_dump(fp);
+ write_dump(fileno(fp));
+
return true;
}
@@ -966,13 +977,13 @@ void debug_dump_heap(const char* file_name) {
std::lock_guard<std::mutex> guard(g_dump_lock);
- FILE* fp = fopen(file_name, "w+e");
- if (fp == nullptr) {
+ int fd = open(file_name, O_RDWR | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0644);
+ if (fd == -1) {
error_log("Unable to create file: %s", file_name);
return;
}
error_log("Dumping to file: %s\n", file_name);
- write_dump(fp);
- fclose(fp);
+ write_dump(fd);
+ close(fd);
}