#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
#include <algorithm>
#include <cmath>
#include <utility>
#include "base/allocator/dispatcher/tls.h"
#include "base/compiler_specific.h"
#include "base/containers/to_vector.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/sampling_heap_profiler/lock_free_address_hash_set.h"
#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
#include "base/threading/thread_local_storage.h"
#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
#include "build/build_config.h"
#include "partition_alloc/partition_alloc.h"
#include "partition_alloc/shim/allocator_shim.h"
#if BUILDFLAG(IS_APPLE)
#include <pthread.h>
#endif
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
#include <sys/prctl.h>
#endif
namespace base {
constexpr uint32_t kMaxStackEntries = …;
namespace {
struct ThreadLocalData { … };
ThreadLocalData* GetThreadLocalData() { … }
#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
BASE_FEATURE(…);
#endif
StackUnwinder;
AllocationSubsystem;
const char* GetAndLeakThreadName() { … }
const char* UpdateAndGetThreadName(const char* name) { … }
[[maybe_unused]] StackUnwinder CheckForDefaultUnwindTables() { … }
StackUnwinder ChooseStackUnwinder() { … }
}
SamplingHeapProfiler::Sample::Sample(size_t size,
size_t total,
uint32_t ordinal)
: … { … }
SamplingHeapProfiler::Sample::Sample(const Sample&) = default;
SamplingHeapProfiler::Sample::~Sample() = default;
SamplingHeapProfiler::SamplingHeapProfiler() = default;
SamplingHeapProfiler::~SamplingHeapProfiler() { … }
uint32_t SamplingHeapProfiler::Start() { … }
void SamplingHeapProfiler::Stop() { … }
void SamplingHeapProfiler::SetSamplingInterval(size_t sampling_interval_bytes) { … }
void SamplingHeapProfiler::SetRecordThreadNames(bool value) { … }
const char* SamplingHeapProfiler::CachedThreadName() { … }
span<const void*> SamplingHeapProfiler::CaptureStackTrace(
span<const void*> frames) { … }
void SamplingHeapProfiler::SampleAdded(void* address,
size_t size,
size_t total,
AllocationSubsystem type,
const char* context) { … }
void SamplingHeapProfiler::CaptureNativeStack(const char* context,
Sample* sample) { … }
const char* SamplingHeapProfiler::RecordString(const char* string) { … }
void SamplingHeapProfiler::SampleRemoved(void* address) { … }
std::vector<SamplingHeapProfiler::Sample> SamplingHeapProfiler::GetSamples(
uint32_t profile_id) { … }
std::vector<const char*> SamplingHeapProfiler::GetStrings() { … }
void SamplingHeapProfiler::Init() { … }
SamplingHeapProfiler* SamplingHeapProfiler::Get() { … }
void SamplingHeapProfiler::OnThreadNameChanged(const char* name) { … }
PoissonAllocationSampler::ScopedMuteHookedSamplesForTesting
SamplingHeapProfiler::MuteHookedSamplesForTesting() { … }
}