summaryrefslogtreecommitdiffstats
path: root/base/allocator
diff options
context:
space:
mode:
authorsque <sque@chromium.org>2016-03-15 12:55:15 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-15 19:56:39 +0000
commitbe8dae533a69fc2c2a71a03193bc59de7570999a (patch)
tree93ea90571aa8a205f59c1ba09e5a7c60879bc606 /base/allocator
parent3cc2071d4e96612b8ee3451b03f640945a4c387f (diff)
downloadchromium_src-be8dae533a69fc2c2a71a03193bc59de7570999a.zip
chromium_src-be8dae533a69fc2c2a71a03193bc59de7570999a.tar.gz
chromium_src-be8dae533a69fc2c2a71a03193bc59de7570999a.tar.bz2
metrics: Connect leak detector to base::allocator
This patch introduces the leak detector's integration layer, which gathers alloc/free info and passes it to the leak detection logic in LeakDetectorImpl. It registers callbacks with the allocator, which are called during alloc and free. These callbacks intercept and sample the alloc and free info. It also provides a notification interface for external objects to receive leak reports. See leak_detector.cc for more info. BUG=chromium:382705 TEST=build successfully, run components_unittests Review URL: https://codereview.chromium.org/1665553002 Cr-Commit-Position: refs/heads/master@{#381293}
Diffstat (limited to 'base/allocator')
-rw-r--r--base/allocator/allocator_extension.cc22
-rw-r--r--base/allocator/allocator_extension.h20
2 files changed, 42 insertions, 0 deletions
diff --git a/base/allocator/allocator_extension.cc b/base/allocator/allocator_extension.cc
index 17682f8..9a3d114 100644
--- a/base/allocator/allocator_extension.cc
+++ b/base/allocator/allocator_extension.cc
@@ -9,6 +9,7 @@
#if defined(USE_TCMALLOC)
#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
#include "third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h"
+#include "third_party/tcmalloc/chromium/src/gperftools/malloc_hook.h"
#endif
namespace base {
@@ -34,5 +35,26 @@ bool IsHeapProfilerRunning() {
return false;
}
+void SetHooks(AllocHookFunc alloc_hook, FreeHookFunc free_hook) {
+// TODO(sque): Use allocator shim layer instead.
+#if defined(USE_TCMALLOC)
+ // Make sure no hooks get overwritten.
+ auto prev_alloc_hook = MallocHook::SetNewHook(alloc_hook);
+ if (alloc_hook)
+ DCHECK(!prev_alloc_hook);
+
+ auto prev_free_hook = MallocHook::SetDeleteHook(free_hook);
+ if (free_hook)
+ DCHECK(!prev_free_hook);
+#endif
+}
+
+int GetCallStack(void** stack, int max_stack_size) {
+#if defined(USE_TCMALLOC)
+ return MallocHook::GetCallerStackTrace(stack, max_stack_size, 0);
+#endif
+ return 0;
+}
+
} // namespace allocator
} // namespace base
diff --git a/base/allocator/allocator_extension.h b/base/allocator/allocator_extension.h
index 64bfd1c..9f2775a 100644
--- a/base/allocator/allocator_extension.h
+++ b/base/allocator/allocator_extension.h
@@ -13,6 +13,10 @@
namespace base {
namespace allocator {
+// Callback types for alloc and free.
+using AllocHookFunc = void (*)(const void*, size_t);
+using FreeHookFunc = void (*)(const void*);
+
// Request that the allocator release any free memory it knows about to the
// system.
BASE_EXPORT void ReleaseFreeMemory();
@@ -25,6 +29,22 @@ BASE_EXPORT bool GetNumericProperty(const char* name, size_t* value);
BASE_EXPORT bool IsHeapProfilerRunning();
+// Register callbacks for alloc and free. Can only store one callback at a time
+// for each of alloc and free.
+BASE_EXPORT void SetHooks(AllocHookFunc alloc_hook, FreeHookFunc free_hook);
+
+// Attempts to unwind the call stack from the current location where this
+// function is being called from. Must be called from a hook function registered
+// by calling SetSingle{Alloc,Free}Hook, directly or indirectly.
+//
+// Arguments:
+// stack: pointer to a pre-allocated array of void*'s.
+// max_stack_size: indicates the size of the array in |stack|.
+//
+// Returns the number of call stack frames stored in |stack|, or 0 if no call
+// stack information is available.
+BASE_EXPORT int GetCallStack(void** stack, int max_stack_size);
+
} // namespace allocator
} // namespace base