OSDN Git Service

Small refactor.
authorChristopher Ferris <cferris@google.com>
Fri, 8 Apr 2016 00:14:53 +0000 (17:14 -0700)
committerChristopher Ferris <cferris@google.com>
Tue, 12 Apr 2016 22:36:53 +0000 (15:36 -0700)
- 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

14 files changed:
libc/malloc_debug/BacktraceData.cpp
libc/malloc_debug/BacktraceData.h
libc/malloc_debug/Config.h
libc/malloc_debug/DebugData.cpp
libc/malloc_debug/DebugData.h
libc/malloc_debug/FreeTrackData.cpp
libc/malloc_debug/FreeTrackData.h
libc/malloc_debug/GuardData.cpp
libc/malloc_debug/GuardData.h
libc/malloc_debug/OptionData.h [new file with mode: 0644]
libc/malloc_debug/TrackData.cpp
libc/malloc_debug/TrackData.h
libc/malloc_debug/debug_disable.cpp
libc/malloc_debug/malloc_debug.cpp

index 400e282..3d46bf0 100644 (file)
 #include "debug_log.h"
 #include "malloc_debug.h"
 
-BacktraceData::BacktraceData(const Config& config, size_t* offset) {
-  size_t hdr_len = sizeof(BacktraceHeader) + sizeof(uintptr_t) * config.backtrace_frames;
-  alloc_offset_ = *offset;
-  *offset += BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
-}
-
-static BacktraceData* g_backtrace_data = nullptr;
-
 static void EnableToggle(int, siginfo_t*, void*) {
-  if (g_backtrace_data->enabled()) {
-    g_backtrace_data->set_enabled(false);
+  if (g_debug->backtrace->enabled()) {
+    g_debug->backtrace->set_enabled(false);
   } else {
-    g_backtrace_data->set_enabled(true);
+    g_debug->backtrace->set_enabled(true);
   }
 }
 
+BacktraceData::BacktraceData(DebugData* debug_data, const Config& config, size_t* offset)
+    : OptionData(debug_data) {
+  size_t hdr_len = sizeof(BacktraceHeader) + sizeof(uintptr_t) * config.backtrace_frames;
+  alloc_offset_ = *offset;
+  *offset += BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
+}
+
 bool BacktraceData::Initialize(const Config& config) {
   enabled_ = config.backtrace_enabled;
   if (config.backtrace_enable_on_signal) {
-    g_backtrace_data = this;
-
     struct sigaction enable_act;
     memset(&enable_act, 0, sizeof(enable_act));
 
index 842e372..dbc3989 100644 (file)
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
 struct Config;
 
-class BacktraceData {
+class BacktraceData : public OptionData {
  public:
-  BacktraceData(const Config& config, size_t* offset);
+  BacktraceData(DebugData* debug_data, const Config& config, size_t* offset);
   virtual ~BacktraceData() = default;
 
   bool Initialize(const Config& config);
index cb1de5a..3ee93b2 100644 (file)
@@ -49,8 +49,8 @@ constexpr size_t MINIMUM_ALIGNMENT_BYTES = 16;
 constexpr size_t MINIMUM_ALIGNMENT_BYTES = 8;
 #endif
 
-// If only one or more of these options is set, then no special header is needed.
-constexpr uint64_t NO_HEADER_OPTIONS = FILL_ON_ALLOC | FILL_ON_FREE | EXPAND_ALLOC;
+// If one or more of these options is set, then a special header is needed.
+constexpr uint64_t HEADER_OPTIONS = FRONT_GUARD | REAR_GUARD | BACKTRACE | FREE_TRACK | LEAK_TRACK;
 
 struct Config {
   bool SetFromProperties();
index 0447566..58cbbcb 100644 (file)
@@ -43,37 +43,37 @@ bool DebugData::Initialize() {
   }
 
   // Check to see if the options that require a header are enabled.
-  if ((config_.options & ~(NO_HEADER_OPTIONS)) != 0) {
+  if (config_.options & HEADER_OPTIONS) {
     need_header_ = true;
 
     // Initialize all of the static header offsets.
     pointer_offset_ = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
 
     if (config_.options & BACKTRACE) {
-      backtrace.reset(new BacktraceData(config_, &pointer_offset_));
+      backtrace.reset(new BacktraceData(this, config_, &pointer_offset_));
       if (!backtrace->Initialize(config_)) {
         return false;
       }
     }
 
     if (config_.options & FRONT_GUARD) {
-      front_guard.reset(new FrontGuardData(config_, &pointer_offset_));
+      front_guard.reset(new FrontGuardData(this, config_, &pointer_offset_));
     }
 
     extra_bytes_ = pointer_offset_;
 
     // Initialize all of the non-header data.
     if (config_.options & REAR_GUARD) {
-      rear_guard.reset(new RearGuardData(config_));
+      rear_guard.reset(new RearGuardData(this, config_));
       extra_bytes_ += config_.rear_guard_bytes;
     }
 
     if (config_.options & FREE_TRACK) {
-      free_track.reset(new FreeTrackData(config_));
+      free_track.reset(new FreeTrackData(this, config_));
     }
 
     if (config_.options & TRACK_ALLOCS) {
-      track.reset(new TrackData());
+      track.reset(new TrackData(this));
     }
   }
 
index 4600b33..7e55512 100644 (file)
@@ -103,4 +103,6 @@ class DebugData {
   DISALLOW_COPY_AND_ASSIGN(DebugData);
 };
 
+extern DebugData* g_debug;
+
 #endif // MALLOC_DEBUG_DEBUGDATA_H
index ed41981..682f93d 100644 (file)
 #include "FreeTrackData.h"
 #include "malloc_debug.h"
 
-FreeTrackData::FreeTrackData(const Config& config)
-    : backtrace_num_frames_(config.free_track_backtrace_num_frames) {
+FreeTrackData::FreeTrackData(DebugData* debug, const Config& config)
+    : OptionData(debug), backtrace_num_frames_(config.free_track_backtrace_num_frames) {
   cmp_mem_.resize(4096);
   memset(cmp_mem_.data(), config.fill_free_value, cmp_mem_.size());
 }
 
-void FreeTrackData::LogFreeError(DebugData& debug, const Header* header,
-                                 const uint8_t* pointer) {
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::LogFreeError(const Header* header, const uint8_t* pointer) {
   error_log(LOG_DIVIDER);
   error_log("+++ ALLOCATION %p USED AFTER FREE", pointer);
-  uint8_t fill_free_value = debug.config().fill_free_value;
+  uint8_t fill_free_value = debug_->config().fill_free_value;
   for (size_t i = 0; i < header->usable_size; i++) {
     if (pointer[i] != fill_free_value) {
       error_log("  pointer[%zu] = 0x%02x (expected 0x%02x)", i, pointer[i], fill_free_value);
@@ -63,10 +60,8 @@ void FreeTrackData::LogFreeError(DebugData& debug, const Header* header,
   error_log(LOG_DIVIDER);
 }
 
-void FreeTrackData::VerifyAndFree(DebugData& debug, const Header* header,
-                                  const void* pointer) {
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::VerifyAndFree(const Header* header) {
+  const void* pointer = debug_->GetPointer(header);
   if (header->tag != DEBUG_FREE_TAG) {
     error_log(LOG_DIVIDER);
     error_log("+++ ALLOCATION %p HAS CORRUPTED HEADER TAG 0x%x AFTER FREE", pointer, header->tag);
@@ -74,11 +69,12 @@ void FreeTrackData::VerifyAndFree(DebugData& debug, const Header* header,
   } else {
     const uint8_t* memory = reinterpret_cast<const uint8_t*>(pointer);
     size_t bytes = header->usable_size;
-    bytes = (bytes < debug.config().fill_on_free_bytes) ? bytes : debug.config().fill_on_free_bytes;
+    bytes = (bytes < debug_->config().fill_on_free_bytes) ? bytes
+        : debug_->config().fill_on_free_bytes;
     while (bytes > 0) {
       size_t bytes_to_cmp = (bytes < cmp_mem_.size()) ? bytes : cmp_mem_.size();
       if (memcmp(memory, cmp_mem_.data(), bytes_to_cmp) != 0) {
-        LogFreeError(debug, header, reinterpret_cast<const uint8_t*>(pointer));
+        LogFreeError(header, reinterpret_cast<const uint8_t*>(pointer));
         break;
       }
       bytes -= bytes_to_cmp;
@@ -94,14 +90,11 @@ void FreeTrackData::VerifyAndFree(DebugData& debug, const Header* header,
   g_dispatch->free(header->orig_pointer);
 }
 
-void FreeTrackData::Add(DebugData& debug, const Header* header) {
-  // Make sure the stl calls below don't call the debug_XXX functions.
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::Add(const Header* header) {
   pthread_mutex_lock(&mutex_);
-  if (list_.size() == debug.config().free_track_allocations) {
+  if (list_.size() == debug_->config().free_track_allocations) {
     const Header* old_header = list_.back();
-    VerifyAndFree(debug, old_header, debug.GetPointer(old_header));
+    VerifyAndFree(old_header);
     list_.pop_back();
   }
 
@@ -118,19 +111,14 @@ void FreeTrackData::Add(DebugData& debug, const Header* header) {
   pthread_mutex_unlock(&mutex_);
 }
 
-void FreeTrackData::VerifyAll(DebugData& debug) {
-  // Make sure the stl calls below don't call the debug_XXX functions.
-  ScopedDisableDebugCalls disable;
-
+void FreeTrackData::VerifyAll() {
   for (const auto& header : list_) {
-    VerifyAndFree(debug, header, debug.GetPointer(header));
+    VerifyAndFree(header);
   }
   list_.clear();
 }
 
 void FreeTrackData::LogBacktrace(const Header* header) {
-  ScopedDisableDebugCalls disable;
-
   auto back_iter = backtraces_.find(header);
   if (back_iter == backtraces_.end()) {
     return;
index 804b5a6..21f845f 100644 (file)
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
-struct Header;
-class DebugData;
-struct Config;
 struct BacktraceHeader;
+struct Config;
+class DebugData;
+struct Header;
 
-class FreeTrackData {
+class FreeTrackData : public OptionData {
  public:
-  FreeTrackData(const Config& config);
+  FreeTrackData(DebugData* debug_data, const Config& config);
   virtual ~FreeTrackData() = default;
 
-  void Add(DebugData& debug, const Header* header);
+  void Add(const Header* header);
 
-  void VerifyAll(DebugData& debug);
+  void VerifyAll();
 
   void LogBacktrace(const Header* header);
 
  private:
-  void LogFreeError(DebugData& debug, const Header* header, const uint8_t* pointer);
-  void VerifyAndFree(DebugData& debug, const Header* header, const void* pointer);
+  void LogFreeError(const Header* header, const uint8_t* pointer);
+  void VerifyAndFree(const Header* header);
 
   pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
   std::deque<const Header*> list_;
index c70e8f1..48961b6 100644 (file)
 #include "malloc_debug.h"
 #include "GuardData.h"
 
-GuardData::GuardData(int init_value, size_t num_bytes) {
+GuardData::GuardData(DebugData* debug_data, int init_value, size_t num_bytes)
+    : OptionData(debug_data) {
   // Create a buffer for fast comparisons of the front guard.
   cmp_mem_.resize(num_bytes);
   memset(cmp_mem_.data(), init_value, cmp_mem_.size());
 }
 
 void GuardData::LogFailure(const Header* header, const void* pointer, const void* data) {
-  ScopedDisableDebugCalls disable;
-
   error_log(LOG_DIVIDER);
   error_log("+++ ALLOCATION %p SIZE %zu HAS A CORRUPTED %s GUARD", pointer,
             header->real_size(), GetTypeName());
@@ -70,8 +69,8 @@ void GuardData::LogFailure(const Header* header, const void* pointer, const void
   error_log(LOG_DIVIDER);
 }
 
-FrontGuardData::FrontGuardData(const Config& config, size_t* offset)
-   : GuardData(config.front_guard_value, config.front_guard_bytes) {
+FrontGuardData::FrontGuardData(DebugData* debug_data, const Config& config, size_t* offset)
+   : GuardData(debug_data, config.front_guard_value, config.front_guard_bytes) {
   // Create a buffer for fast comparisons of the front guard.
   cmp_mem_.resize(config.front_guard_bytes);
   memset(cmp_mem_.data(), config.front_guard_value, cmp_mem_.size());
@@ -80,22 +79,22 @@ FrontGuardData::FrontGuardData(const Config& config, size_t* offset)
   *offset += config.front_guard_bytes;
 }
 
-bool FrontGuardData::Valid(DebugData& debug, const Header* header) {
-  return GuardData::Valid(debug.GetFrontGuard(header));
+bool FrontGuardData::Valid(const Header* header) {
+  return GuardData::Valid(debug_->GetFrontGuard(header));
 }
 
-void FrontGuardData::LogFailure(DebugData& debug, const Header* header) {
-  GuardData::LogFailure(header, debug.GetPointer(header), debug.GetFrontGuard(header));
+void FrontGuardData::LogFailure(const Header* header) {
+  GuardData::LogFailure(header, debug_->GetPointer(header), debug_->GetFrontGuard(header));
 }
 
-RearGuardData::RearGuardData(const Config& config)
-    : GuardData(config.rear_guard_value, config.rear_guard_bytes) {
+RearGuardData::RearGuardData(DebugData* debug_data, const Config& config)
+    : GuardData(debug_data, config.rear_guard_value, config.rear_guard_bytes) {
 }
 
-bool RearGuardData::Valid(DebugData& debug, const Header* header) {
-  return GuardData::Valid(debug.GetRearGuard(header));
+bool RearGuardData::Valid(const Header* header) {
+  return GuardData::Valid(debug_->GetRearGuard(header));
 }
 
-void RearGuardData::LogFailure(DebugData& debug, const Header* header) {
-  GuardData::LogFailure(header, debug.GetPointer(header), debug.GetRearGuard(header));
+void RearGuardData::LogFailure(const Header* header) {
+  GuardData::LogFailure(header, debug_->GetPointer(header), debug_->GetRearGuard(header));
 }
index 4de2702..bfb3949 100644 (file)
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
 class DebugData;
 struct Header;
 struct Config;
 
-class GuardData {
+class GuardData : public OptionData {
  public:
-  GuardData(int init_value, size_t num_bytes);
+  GuardData(DebugData* debug_data, int init_value, size_t num_bytes);
   virtual ~GuardData() = default;
 
   bool Valid(void* data) { return memcmp(data, cmp_mem_.data(), cmp_mem_.size()) == 0; }
@@ -60,12 +62,12 @@ class GuardData {
 
 class FrontGuardData : public GuardData {
  public:
-  FrontGuardData(const Config& config, size_t* offset);
+  FrontGuardData(DebugData* debug_data, const Config& config, size_t* offset);
   virtual ~FrontGuardData() = default;
 
-  bool Valid(DebugData& debug, const Header* header);
+  bool Valid(const Header* header);
 
-  void LogFailure(DebugData& debug, const Header* header);
+  void LogFailure(const Header* header);
 
   size_t offset() { return offset_; }
 
@@ -79,12 +81,12 @@ class FrontGuardData : public GuardData {
 
 class RearGuardData : public GuardData {
  public:
-  RearGuardData(const Config& config);
+  RearGuardData(DebugData* debug_data, const Config& config);
   virtual ~RearGuardData() = default;
 
-  bool Valid(DebugData& debug, const Header* header);
+  bool Valid(const Header* header);
 
-  void LogFailure(DebugData& debug, const Header* header);
+  void LogFailure(const Header* header);
 
  private:
   const char* GetTypeName() override { return "REAR"; }
diff --git a/libc/malloc_debug/OptionData.h b/libc/malloc_debug/OptionData.h
new file mode 100644 (file)
index 0000000..80190f5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef DEBUG_MALLOC_OPTIONDATA_H
+#define DEBUG_MALLOC_OPTIONDATA_H
+
+// Forward Declarations
+class DebugData;
+
+class OptionData {
+ public:
+  OptionData(DebugData* debug) : debug_(debug) {}
+  ~OptionData() = default;
+
+ protected:
+  DebugData* debug_;
+
+  DISALLOW_COPY_AND_ASSIGN(OptionData);
+};
+
+#endif // MALLOC_DEBUG_OPTIONDATA_H
index c9828d0..18f428b 100644 (file)
 #include "malloc_debug.h"
 #include "TrackData.h"
 
-void TrackData::GetList(std::vector<const Header*>* list) {
-  ScopedDisableDebugCalls disable;
+TrackData::TrackData(DebugData* debug_data) : OptionData(debug_data) {
+}
 
+void TrackData::GetList(std::vector<const Header*>* list) {
   for (const auto& header : headers_) {
     list->push_back(header);
   }
@@ -59,8 +60,6 @@ void TrackData::GetList(std::vector<const Header*>* list) {
 }
 
 void TrackData::Add(const Header* header, bool backtrace_found) {
-  ScopedDisableDebugCalls disable;
-
   pthread_mutex_lock(&mutex_);
   if (backtrace_found) {
     total_backtrace_allocs_++;
@@ -70,8 +69,6 @@ void TrackData::Add(const Header* header, bool backtrace_found) {
 }
 
 void TrackData::Remove(const Header* header, bool backtrace_found) {
-  ScopedDisableDebugCalls disable;
-
   pthread_mutex_lock(&mutex_);
   headers_.erase(header);
   if (backtrace_found) {
@@ -81,26 +78,22 @@ void TrackData::Remove(const Header* header, bool backtrace_found) {
 }
 
 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;
-
+void TrackData::DisplayLeaks() {
   std::vector<const Header*> list;
   GetList(&list);
 
   size_t track_count = 0;
   for (const auto& header : list) {
     error_log("+++ %s leaked block of size %zu at %p (leak %zu of %zu)", getprogname(),
-              header->real_size(), debug.GetPointer(header), ++track_count, list.size());
-    if (debug.config().options & BACKTRACE) {
-      BacktraceHeader* back_header = debug.GetAllocBacktrace(header);
+              header->real_size(), debug_->GetPointer(header), ++track_count, list.size());
+    if (debug_->config().options & BACKTRACE) {
+      BacktraceHeader* back_header = debug_->GetAllocBacktrace(header);
       if (back_header->num_frames > 0) {
         error_log("Backtrace at time of allocation:");
         backtrace_log(&back_header->frames[0], back_header->num_frames);
@@ -110,15 +103,15 @@ void TrackData::DisplayLeaks(DebugData& debug) {
   }
 }
 
-void TrackData::GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
-                        size_t* info_size, size_t* total_memory, size_t* backtrace_size) {
+void TrackData::GetInfo(uint8_t** info, size_t* overall_size, size_t* info_size,
+                        size_t* total_memory, size_t* backtrace_size) {
   ScopedPthreadMutexLocker scoped(&mutex_);
 
   if (headers_.size() == 0 || total_backtrace_allocs_ == 0) {
     return;
   }
 
-  *backtrace_size = debug.config().backtrace_frames;
+  *backtrace_size = debug_->config().backtrace_frames;
   *info_size = sizeof(size_t) * 2 + sizeof(uintptr_t) * *backtrace_size;
   *info = reinterpret_cast<uint8_t*>(g_dispatch->calloc(*info_size, total_backtrace_allocs_));
   if (*info == nullptr) {
@@ -131,7 +124,7 @@ void TrackData::GetInfo(DebugData& debug, uint8_t** info, size_t* overall_size,
 
   uint8_t* data = *info;
   for (const auto& header : list) {
-    BacktraceHeader* back_header = debug.GetAllocBacktrace(header);
+    BacktraceHeader* back_header = debug_->GetAllocBacktrace(header);
     if (back_header->num_frames > 0) {
       memcpy(data, &header->size, sizeof(size_t));
       memcpy(&data[sizeof(size_t)], &back_header->num_frames, sizeof(size_t));
index 1234316..fcd8f2a 100644 (file)
 
 #include <private/bionic_macros.h>
 
+#include "OptionData.h"
+
 // Forward declarations.
 struct Header;
 struct Config;
 class DebugData;
 
-class TrackData {
+class TrackData : public OptionData {
  public:
-  TrackData() = default;
+  TrackData(DebugData* debug_data);
   virtual ~TrackData() = default;
 
   void GetList(std::vector<const Header*>* list);
@@ -55,10 +57,10 @@ class TrackData {
 
   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);
+  void GetInfo(uint8_t** info, size_t* overall_size, size_t* info_size,
+               size_t* total_memory, size_t* backtrace_size);
 
-  void DisplayLeaks(DebugData& debug);
+  void DisplayLeaks();
 
   void PrepareFork() { pthread_mutex_lock(&mutex_); }
   void PostForkParent() { pthread_mutex_unlock(&mutex_); }
index af0264b..b80ba8c 100644 (file)
@@ -32,7 +32,6 @@
 #include "debug_disable.h"
 #include "debug_log.h"
 
-extern DebugData* g_debug;
 pthread_key_t g_disable_key;
 
 bool DebugCallsDisabled() {
index 1ee7689..5da5b88 100644 (file)
@@ -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;