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
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index f55d488..4f86579 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -88,7 +88,14 @@
   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 @@
   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 @@
     }
 
     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 {