From 55a89a48f41da349735627c2ae8985895955b1ca Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Thu, 7 Apr 2016 17:14:53 -0700 Subject: 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 --- libc/malloc_debug/malloc_debug.cpp | 89 ++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 33 deletions(-) (limited to 'libc/malloc_debug/malloc_debug.cpp') diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp index 1ee76897d..5da5b88e4 100644 --- a/libc/malloc_debug/malloc_debug.cpp +++ b/libc/malloc_debug/malloc_debug.cpp @@ -114,8 +114,6 @@ static void InitAtfork() { } 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 @@ 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; @@ -217,11 +214,11 @@ void debug_finalize() { } 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 @@ void debug_get_malloc_leak_info(uint8_t** info, size_t* overall_size, 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; +size_t debug_malloc_usable_size(void* pointer) { + if (DebugCallsDisabled() || pointer == nullptr) { + return g_dispatch->malloc_usable_size(pointer); } + ScopedDisableDebugCalls disable; - return header->usable_size; + return internal_malloc_usable_size(pointer); } -void* debug_malloc(size_t size) { - if (DebugCallsDisabled()) { - return g_dispatch->malloc(size); - } - +static void *internal_malloc(size_t size) { if (size == 0) { size = 1; } @@ -312,7 +314,7 @@ void* debug_malloc(size_t size) { } 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 @@ void* debug_malloc(size_t size) { 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 @@ void debug_free(void* pointer) { 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 @@ void debug_free(void* pointer) { // 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 @@ void* debug_memalign(size_t alignment, size_t bytes) { } 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 @@ void* debug_realloc(void* pointer, size_t bytes) { 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 @@ void* debug_realloc(void* pointer, size_t bytes) { // 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 @@ void* debug_realloc(void* pointer, size_t bytes) { 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 @@ void* debug_realloc(void* pointer, size_t bytes) { 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 @@ void* debug_realloc(void* pointer, size_t bytes) { } 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 @@ void* debug_calloc(size_t nmemb, size_t bytes) { if (DebugCallsDisabled()) { return g_dispatch->calloc(nmemb, bytes); } + ScopedDisableDebugCalls disable; size_t size; if (__builtin_mul_overflow(nmemb, bytes, &size)) { @@ -645,6 +667,7 @@ ssize_t debug_malloc_backtrace(void* pointer, uintptr_t* frames, size_t frame_co if (DebugCallsDisabled() || pointer == nullptr) { return 0; } + ScopedDisableDebugCalls disable; if (g_debug->need_header()) { Header* header; -- cgit v1.2.3