Small refactor.
- Move all ScopedDisableDebugCalls into the debug_XXX calls. This avoids
any issues that might arise where every part of the code needs to properly
guard anything that might allocate. Instead everything is already guarded.
- Add a pointer to debug_data in all of the XXData classes. This avoids
calling individual functions passing in the debug_data pointer.
- Flip the NO_HEADER_OPTIONS to an explicit HEADER_OPTIONS list since fewer
options actually require a header.
- Move the extern of g_debug to the DebugData.h header.
Change-Id: Ia213a391b4a44d9ce122a709d09fe4f1b5426f36
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 1ee7689..5da5b88 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -114,8 +114,6 @@
}
static void LogTagError(const Header* header, const void* pointer, const char* name) {
- ScopedDisableDebugCalls disable;
-
error_log(LOG_DIVIDER);
if (header->tag == DEBUG_FREE_TAG) {
error_log("+++ ALLOCATION %p USED AFTER FREE (%s)", pointer, name);
@@ -165,7 +163,6 @@
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;
@@ -217,11 +214,11 @@
}
if (g_debug->config().options & FREE_TRACK) {
- g_debug->free_track->VerifyAll(*g_debug);
+ g_debug->free_track->VerifyAll();
}
if (g_debug->config().options & LEAK_TRACK) {
- g_debug->track->DisplayLeaks(*g_debug);
+ g_debug->track->DisplayLeaks();
}
DebugDisableSet(true);
@@ -257,32 +254,37 @@
return;
}
- g_debug->track->GetInfo(*g_debug, info, overall_size, info_size, total_memory, backtrace_size);
+ g_debug->track->GetInfo(info, overall_size, info_size, total_memory, backtrace_size);
}
void debug_free_malloc_leak_info(uint8_t* info) {
g_dispatch->free(info);
}
-size_t debug_malloc_usable_size(void* pointer) {
- if (DebugCallsDisabled() || !g_debug->need_header() || pointer == nullptr) {
+static size_t internal_malloc_usable_size(void* pointer) {
+ if (g_debug->need_header()) {
+ Header* header = g_debug->GetHeader(pointer);
+ if (header->tag != DEBUG_TAG) {
+ LogTagError(header, pointer, "malloc_usable_size");
+ return 0;
+ }
+
+ return header->usable_size;
+ } else {
return g_dispatch->malloc_usable_size(pointer);
}
-
- Header* header = g_debug->GetHeader(pointer);
- if (header->tag != DEBUG_TAG) {
- LogTagError(header, pointer, "malloc_usable_size");
- return 0;
- }
-
- return header->usable_size;
}
-void* debug_malloc(size_t size) {
- if (DebugCallsDisabled()) {
- return g_dispatch->malloc(size);
+size_t debug_malloc_usable_size(void* pointer) {
+ if (DebugCallsDisabled() || pointer == nullptr) {
+ return g_dispatch->malloc_usable_size(pointer);
}
+ ScopedDisableDebugCalls disable;
+ return internal_malloc_usable_size(pointer);
+}
+
+static void *internal_malloc(size_t size) {
if (size == 0) {
size = 1;
}
@@ -312,7 +314,7 @@
}
if (pointer != nullptr && g_debug->config().options & FILL_ON_ALLOC) {
- size_t bytes = debug_malloc_usable_size(pointer);
+ size_t bytes = internal_malloc_usable_size(pointer);
size_t fill_bytes = g_debug->config().fill_on_alloc_bytes;
bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
memset(pointer, g_debug->config().fill_alloc_value, bytes);
@@ -320,11 +322,16 @@
return pointer;
}
-void debug_free(void* pointer) {
- if (DebugCallsDisabled() || pointer == nullptr) {
- return g_dispatch->free(pointer);
+void* debug_malloc(size_t size) {
+ if (DebugCallsDisabled()) {
+ return g_dispatch->malloc(size);
}
+ ScopedDisableDebugCalls disable;
+ return internal_malloc(size);
+}
+
+static void internal_free(void* pointer) {
void* free_pointer = pointer;
size_t bytes;
Header* header;
@@ -337,13 +344,13 @@
free_pointer = header->orig_pointer;
if (g_debug->config().options & FRONT_GUARD) {
- if (!g_debug->front_guard->Valid(*g_debug, header)) {
- g_debug->front_guard->LogFailure(*g_debug, header);
+ if (!g_debug->front_guard->Valid(header)) {
+ g_debug->front_guard->LogFailure(header);
}
}
if (g_debug->config().options & REAR_GUARD) {
- if (!g_debug->rear_guard->Valid(*g_debug, header)) {
- g_debug->rear_guard->LogFailure(*g_debug, header);
+ if (!g_debug->rear_guard->Valid(header)) {
+ g_debug->rear_guard->LogFailure(header);
}
}
@@ -374,16 +381,26 @@
// frees at the same time and we wind up trying to really free this
// pointer from another thread, while still trying to free it in
// this function.
- g_debug->free_track->Add(*g_debug, header);
+ g_debug->free_track->Add(header);
} else {
g_dispatch->free(free_pointer);
}
}
+void debug_free(void* pointer) {
+ if (DebugCallsDisabled() || pointer == nullptr) {
+ return g_dispatch->free(pointer);
+ }
+ ScopedDisableDebugCalls disable;
+
+ internal_free(pointer);
+}
+
void* debug_memalign(size_t alignment, size_t bytes) {
if (DebugCallsDisabled()) {
return g_dispatch->memalign(alignment, bytes);
}
+ ScopedDisableDebugCalls disable;
if (bytes == 0) {
bytes = 1;
@@ -438,11 +455,12 @@
}
if (pointer != nullptr && g_debug->config().options & FILL_ON_ALLOC) {
- size_t bytes = debug_malloc_usable_size(pointer);
+ size_t bytes = internal_malloc_usable_size(pointer);
size_t fill_bytes = g_debug->config().fill_on_alloc_bytes;
bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
memset(pointer, g_debug->config().fill_alloc_value, bytes);
}
+
return pointer;
}
@@ -450,13 +468,14 @@
if (DebugCallsDisabled()) {
return g_dispatch->realloc(pointer, bytes);
}
+ ScopedDisableDebugCalls disable;
if (pointer == nullptr) {
- return debug_malloc(bytes);
+ return internal_malloc(bytes);
}
if (bytes == 0) {
- debug_free(pointer);
+ internal_free(pointer);
return nullptr;
}
@@ -486,6 +505,7 @@
// Same size, do nothing.
if (real_size == header->real_size()) {
+ // Do not bother recording, this is essentially a nop.
return pointer;
}
@@ -502,11 +522,12 @@
memset(g_debug->GetRearGuard(header), g_debug->config().rear_guard_value,
g_debug->config().rear_guard_bytes);
}
+ // Do not bother recording, this is essentially a nop.
return pointer;
}
// Allocate the new size.
- new_pointer = debug_malloc(bytes);
+ new_pointer = internal_malloc(bytes);
if (new_pointer == nullptr) {
errno = ENOMEM;
return nullptr;
@@ -514,7 +535,7 @@
prev_size = header->usable_size;
memcpy(new_pointer, pointer, prev_size);
- debug_free(pointer);
+ internal_free(pointer);
} else {
prev_size = g_dispatch->malloc_usable_size(pointer);
new_pointer = g_dispatch->realloc(pointer, real_size);
@@ -524,7 +545,7 @@
}
if (g_debug->config().options & FILL_ON_ALLOC) {
- size_t bytes = debug_malloc_usable_size(new_pointer);
+ size_t bytes = internal_malloc_usable_size(new_pointer);
if (bytes > g_debug->config().fill_on_alloc_bytes) {
bytes = g_debug->config().fill_on_alloc_bytes;
}
@@ -541,6 +562,7 @@
if (DebugCallsDisabled()) {
return g_dispatch->calloc(nmemb, bytes);
}
+ ScopedDisableDebugCalls disable;
size_t size;
if (__builtin_mul_overflow(nmemb, bytes, &size)) {
@@ -645,6 +667,7 @@
if (DebugCallsDisabled() || pointer == nullptr) {
return 0;
}
+ ScopedDisableDebugCalls disable;
if (g_debug->need_header()) {
Header* header;