diff options
author | Christopher Ferris <cferris@google.com> | 2016-01-28 18:35:05 -0800 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2016-01-29 15:19:22 -0800 |
commit | 7993b80f894db20af4d1d154221c42fea6171a3d (patch) | |
tree | fc99d36000a8f0853224d75296d96509a730ee05 /libc/malloc_debug/malloc_debug.cpp | |
parent | 50647711ebaf2360aca05cc94a2fdf431c1a153e (diff) |
Add better free tracking.
Included in this change:
- Change the tag when a pointer is freed so it's easy to detect if
an already freed pointer is being used.
- Move the free backtrace out of the header. This backtrace is only
used under only some circumstances, so no need to allocate space
in all headers for it.
- Add new option free_track_backtrace_num_frames to specify how many
frames to record when the free occurs. This removes the dependency
on the backtrace option to get backtraces.
Bug: 26739265
Change-Id: I76f5209507dcf46af67ada162a7cb2bf282116f2
Diffstat (limited to 'libc/malloc_debug/malloc_debug.cpp')
-rw-r--r-- | libc/malloc_debug/malloc_debug.cpp | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp index f55d48822..4f8657969 100644 --- a/libc/malloc_debug/malloc_debug.cpp +++ b/libc/malloc_debug/malloc_debug.cpp @@ -88,7 +88,14 @@ static void LogTagError(const Header* header, const void* pointer, const char* n ScopedDisableDebugCalls disable; error_log(LOG_DIVIDER); - error_log("+++ ALLOCATION %p HAS INVALID TAG %" PRIx32 " (%s)", pointer, header->tag, name); + if (header->tag == DEBUG_FREE_TAG) { + error_log("+++ ALLOCATION %p USED AFTER FREE (%s)", pointer, name); + if (g_debug->config().options & FREE_TRACK) { + g_debug->free_track->LogBacktrace(header); + } + } else { + error_log("+++ ALLOCATION %p HAS INVALID TAG %" PRIx32 " (%s)", pointer, header->tag, name); + } error_log("Backtrace at time of failure:"); std::vector<uintptr_t> frames(64); size_t frame_num = backtrace_get(frames.data(), frames.size()); @@ -129,14 +136,12 @@ 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()) { - back_header->num_frames = backtrace_get(&back_header->frames[0], - g_debug->config().backtrace_frames); + back_header->num_frames = backtrace_get( + &back_header->frames[0], g_debug->config().backtrace_frames); backtrace_found = back_header->num_frames > 0; } else { back_header->num_frames = 0; } - back_header = g_debug->GetFreeBacktrace(header); - back_header->num_frames = 0; } if (g_debug->config().options & TRACK_ALLOCS) { @@ -313,18 +318,12 @@ void debug_free(void* pointer) { } if (g_debug->config().options & FREE_TRACK) { - // Only log the free backtrace if we are using the free track feature. - if ((g_debug->config().options & BACKTRACE) && g_debug->backtrace->enabled()) { - BacktraceHeader* back_header = g_debug->GetFreeBacktrace(header); - back_header->num_frames = backtrace_get(&back_header->frames[0], - g_debug->config().backtrace_frames); - } - g_debug->free_track->Add(*g_debug, header); // Do not free this pointer just yet. free_pointer = nullptr; } + header->tag = DEBUG_FREE_TAG; bytes = header->usable_size; } else { |