Commit 52601a56 authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

[sampling heap profiler] Support stack collection on Android

BUG=803276

Change-Id: I60d7925104b8614aa68c135d52f6089a76675d22
Reviewed-on: https://chromium-review.googlesource.com/1128630Reviewed-by: default avatarSiddhartha S <ssid@chromium.org>
Commit-Queue: Alexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573880}
parent f5231abd
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
#include "base/threading/thread_local_storage.h" #include "base/threading/thread_local_storage.h"
#include "build/build_config.h" #include "build/build_config.h"
#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
defined(OFFICIAL_BUILD)
#include "base/trace_event/cfi_backtrace_android.h"
#endif
namespace base { namespace base {
using base::allocator::AllocatorDispatch; using base::allocator::AllocatorDispatch;
...@@ -231,6 +236,14 @@ void SamplingHeapProfiler::SetHooksInstallCallback( ...@@ -231,6 +236,14 @@ void SamplingHeapProfiler::SetHooksInstallCallback(
} }
uint32_t SamplingHeapProfiler::Start() { uint32_t SamplingHeapProfiler::Start() {
#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
defined(OFFICIAL_BUILD)
if (!base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()
->can_unwind_stack_frames()) {
LOG(WARNING) << "Sampling heap profiler: Stack unwinding is not available.";
return 0;
}
#endif
InstallAllocatorHooksOnce(); InstallAllocatorHooksOnce();
base::subtle::Barrier_AtomicIncrement(&g_running, 1); base::subtle::Barrier_AtomicIncrement(&g_running, 1);
return last_sample_ordinal_; return last_sample_ordinal_;
...@@ -309,16 +322,31 @@ void SamplingHeapProfiler::RecordAlloc(void* address, ...@@ -309,16 +322,31 @@ void SamplingHeapProfiler::RecordAlloc(void* address,
void SamplingHeapProfiler::RecordStackTrace(Sample* sample, void SamplingHeapProfiler::RecordStackTrace(Sample* sample,
uint32_t skip_frames) { uint32_t skip_frames) {
#if !defined(OS_NACL) #if !defined(OS_NACL)
// TODO(alph): Consider using debug::TraceStackFramePointers. It should be constexpr uint32_t kMaxStackEntries = 256;
// somewhat faster than base::debug::StackTrace. constexpr uint32_t kSkipProfilerOwnFrames = 2;
base::debug::StackTrace trace;
size_t count;
void* const* addresses = const_cast<void* const*>(trace.Addresses(&count));
const uint32_t kSkipProfilerOwnFrames = 2;
skip_frames += kSkipProfilerOwnFrames; skip_frames += kSkipProfilerOwnFrames;
#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
defined(OFFICIAL_BUILD)
const void* frames[kMaxStackEntries];
size_t frame_count =
base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()->Unwind(
frames, kMaxStackEntries);
#elif BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
const void* frames[kMaxStackEntries];
size_t frame_count = base::debug::TraceStackFramePointers(
frames, kMaxStackEntries, skip_frames);
skip_frames = 0;
#else
// Fall-back to capturing the stack with base::debug::StackTrace,
// which is likely slower, but more reliable.
base::debug::StackTrace stack_trace(kMaxStackEntries);
size_t frame_count = 0;
const void* const* frames = stack_trace.Addresses(&frame_count);
#endif
sample->stack.insert( sample->stack.insert(
sample->stack.end(), &addresses[skip_frames], sample->stack.end(), const_cast<void**>(&frames[skip_frames]),
&addresses[std::max(count, static_cast<size_t>(skip_frames))]); const_cast<void**>(&frames[std::max<size_t>(frame_count, skip_frames)]));
#endif #endif
} }
......
...@@ -105,7 +105,7 @@ class BASE_EXPORT SamplingHeapProfiler { ...@@ -105,7 +105,7 @@ class BASE_EXPORT SamplingHeapProfiler {
std::stack<std::unique_ptr<LockFreeAddressHashSet>> sampled_addresses_stack_; std::stack<std::unique_ptr<LockFreeAddressHashSet>> sampled_addresses_stack_;
std::unordered_map<void*, Sample> samples_; std::unordered_map<void*, Sample> samples_;
std::vector<SamplesObserver*> observers_; std::vector<SamplesObserver*> observers_;
uint32_t last_sample_ordinal_ = 0; uint32_t last_sample_ordinal_ = 1;
static SamplingHeapProfiler* instance_; static SamplingHeapProfiler* instance_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment