Export malloc_iterate and friends
Export malloc_iterate, malloc_enable, and malloc_disable to be used by
libmemunreachable.
Change-Id: I08a50349af82a95d096b6b4cbac37ababe4b9b06
diff --git a/libc/malloc_debug/TrackData.cpp b/libc/malloc_debug/TrackData.cpp
index e5260a9..c9828d0 100644
--- a/libc/malloc_debug/TrackData.cpp
+++ b/libc/malloc_debug/TrackData.cpp
@@ -44,7 +44,7 @@
#include "malloc_debug.h"
#include "TrackData.h"
-void TrackData::GetList(std::vector<Header*>* list) {
+void TrackData::GetList(std::vector<const Header*>* list) {
ScopedDisableDebugCalls disable;
for (const auto& header : headers_) {
@@ -52,13 +52,13 @@
}
// Sort by the size of the allocation.
- std::sort(list->begin(), list->end(), [](Header* a, Header* b) {
+ std::sort(list->begin(), list->end(), [](const Header* a, const Header* b) {
if (a->size == b->size) return a < b;
return a->size > b->size;
});
}
-void TrackData::Add(Header* header, bool backtrace_found) {
+void TrackData::Add(const Header* header, bool backtrace_found) {
ScopedDisableDebugCalls disable;
pthread_mutex_lock(&mutex_);
@@ -69,7 +69,7 @@
pthread_mutex_unlock(&mutex_);
}
-void TrackData::Remove(Header* header, bool backtrace_found) {
+void TrackData::Remove(const Header* header, bool backtrace_found) {
ScopedDisableDebugCalls disable;
pthread_mutex_lock(&mutex_);
@@ -80,10 +80,19 @@
pthread_mutex_unlock(&mutex_);
}
+bool TrackData::Contains(const Header* header) {
+ ScopedDisableDebugCalls disable;
+
+ pthread_mutex_lock(&mutex_);
+ bool found = headers_.count(header);
+ pthread_mutex_unlock(&mutex_);
+ return found;
+}
+
void TrackData::DisplayLeaks(DebugData& debug) {
ScopedDisableDebugCalls disable;
- std::vector<Header*> list;
+ std::vector<const Header*> list;
GetList(&list);
size_t track_count = 0;
@@ -117,7 +126,7 @@
}
*overall_size = *info_size * total_backtrace_allocs_;
- std::vector<Header*> list;
+ std::vector<const Header*> list;
GetList(&list);
uint8_t* data = *info;
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
index dcf0ede..1234316 100644
--- a/libc/malloc_debug/TrackData.h
+++ b/libc/malloc_debug/TrackData.h
@@ -47,11 +47,13 @@
TrackData() = default;
virtual ~TrackData() = default;
- void GetList(std::vector<Header*>* list);
+ void GetList(std::vector<const Header*>* list);
- void Add(Header* header, bool backtrace_found);
+ void Add(const Header* header, bool backtrace_found);
- void Remove(Header* header, bool backtrace_found);
+ void Remove(const Header* header, bool backtrace_found);
+
+ bool Contains(const Header *header);
void GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
size_t* info_size, size_t* total_memory, size_t* backtrace_size);
@@ -64,7 +66,7 @@
private:
pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
- std::unordered_set<Header*> headers_;
+ std::unordered_set<const Header*> headers_;
size_t total_backtrace_allocs_ = 0;
DISALLOW_COPY_AND_ASSIGN(TrackData);
diff --git a/libc/malloc_debug/exported32.map b/libc/malloc_debug/exported32.map
index aef8818..8f994f1 100644
--- a/libc/malloc_debug/exported32.map
+++ b/libc/malloc_debug/exported32.map
@@ -6,8 +6,11 @@
debug_free_malloc_leak_info;
debug_get_malloc_leak_info;
debug_initialize;
+ debug_iterate;
debug_mallinfo;
debug_malloc;
+ debug_malloc_disable;
+ debug_malloc_enable;
debug_malloc_usable_size;
debug_memalign;
debug_posix_memalign;
diff --git a/libc/malloc_debug/exported64.map b/libc/malloc_debug/exported64.map
index 70fd581..8c47449 100644
--- a/libc/malloc_debug/exported64.map
+++ b/libc/malloc_debug/exported64.map
@@ -6,8 +6,11 @@
debug_free_malloc_leak_info;
debug_get_malloc_leak_info;
debug_initialize;
+ debug_iterate;
debug_mallinfo;
debug_malloc;
+ debug_malloc_disable;
+ debug_malloc_enable;
debug_malloc_usable_size;
debug_memalign;
debug_posix_memalign;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index dcc6048..5b6e415 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -76,6 +76,10 @@
void* debug_calloc(size_t nmemb, size_t bytes);
struct mallinfo debug_mallinfo();
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);
+void debug_malloc_disable();
+void debug_malloc_enable();
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
void* debug_pvalloc(size_t bytes);
@@ -569,6 +573,49 @@
return (*memptr != nullptr) ? 0 : ENOMEM;
}
+int debug_iterate(uintptr_t base, size_t size,
+ void (*callback)(uintptr_t base, size_t size, void* arg), void* arg) {
+ // Can't allocate, malloc is disabled
+ // Manual capture of the arguments to pass to the lambda below as void* arg
+ struct iterate_ctx {
+ decltype(callback) callback;
+ decltype(arg) arg;
+ } ctx = { callback, arg };
+
+ return g_dispatch->iterate(base, size,
+ [](uintptr_t base, size_t size, void* arg) {
+ const iterate_ctx* ctx = reinterpret_cast<iterate_ctx*>(arg);
+ const void* pointer = reinterpret_cast<void*>(base);
+ if (g_debug->need_header()) {
+ const Header* header = reinterpret_cast<const Header*>(pointer);
+ if (g_debug->config().options & TRACK_ALLOCS) {
+ if (g_debug->track->Contains(header)) {
+ // Return just the body of the allocation if we're sure the header exists
+ ctx->callback(reinterpret_cast<uintptr_t>(g_debug->GetPointer(header)),
+ header->real_size(), ctx->arg);
+ return;
+ }
+ }
+ }
+ // Fall back to returning the whole allocation
+ ctx->callback(base, size, ctx->arg);
+ }, &ctx);
+}
+
+void debug_malloc_disable() {
+ g_dispatch->malloc_disable();
+ if (g_debug->track) {
+ g_debug->track->PrepareFork();
+ }
+}
+
+void debug_malloc_enable() {
+ if (g_debug->track) {
+ g_debug->track->PostForkParent();
+ }
+ g_dispatch->malloc_enable();
+}
+
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
void* debug_pvalloc(size_t bytes) {
if (DebugCallsDisabled()) {
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index b316e8a..28729e8 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -121,6 +121,9 @@
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
nullptr,
#endif
+ nullptr,
+ nullptr,
+ nullptr,
};
void VerifyAllocCalls() {