diff options
author | sque <sque@chromium.org> | 2016-03-15 12:55:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-15 19:56:39 +0000 |
commit | be8dae533a69fc2c2a71a03193bc59de7570999a (patch) | |
tree | 93ea90571aa8a205f59c1ba09e5a7c60879bc606 /base/allocator | |
parent | 3cc2071d4e96612b8ee3451b03f640945a4c387f (diff) | |
download | chromium_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.cc | 22 | ||||
-rw-r--r-- | base/allocator/allocator_extension.h | 20 |
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 |