#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
#include <limits>
#include <set>
#include <string_view>
#include "base/android/library_loader/anchor_functions.h"
#include "base/debug/leak_annotations.h"
#include "base/debug/stack_trace.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/hash.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/process/process.h"
#include "base/profiler/sampling_profiler_thread_token.h"
#include "base/profiler/stack_sampling_profiler.h"
#include "base/strings/strcat.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/thread_annotations.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_log.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "services/tracing/public/cpp/buildflags.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
#include "services/tracing/public/cpp/perfetto/producer_client.h"
#include "third_party/perfetto/protos/perfetto/trace/interned_data/interned_data.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/profiling/profile_common.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/profiling/profile_packet.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/trace_packet.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_APPLE)
#include "base/profiler/thread_delegate_posix.h"
#define INITIALIZE_THREAD_DELEGATE_POSIX …
#else
#define INITIALIZE_THREAD_DELEGATE_POSIX …
#endif
#if ANDROID_ARM64_UNWINDING_SUPPORTED || ANDROID_CFI_UNWINDING_SUPPORTED
#include <dlfcn.h>
#include "base/debug/elf_reader.h"
#endif
#if BUILDFLAG(ENABLE_LOADER_LOCK_SAMPLING)
#include "services/tracing/public/cpp/stack_sampling/loader_lock_sampling_thread_win.h"
#endif
StreamingProfilePacketHandle;
TracePacketHandle;
namespace tracing {
namespace {
#if ANDROID_ARM64_UNWINDING_SUPPORTED || ANDROID_CFI_UNWINDING_SUPPORTED
extern "C" {
extern char __executable_start;
}
bool is_chrome_address(uintptr_t pc) {
return pc >= base::android::kStartOfText && pc < base::android::kEndOfText;
}
uintptr_t executable_start_addr() {
return reinterpret_cast<uintptr_t>(&__executable_start);
}
#endif
TracingSamplerProfiler* g_main_thread_instance = …;
class TracingSamplerProfilerDataSource;
TracingSamplerProfilerDataSource* g_sampler_profiler_ds_for_test = …;
class TracingSamplerProfilerDataSource
: public PerfettoTracedProcess::DataSourceBase { … };
DataSourceProxy;
std::atomic<uint32_t>
TracingSamplerProfilerDataSource::incremental_state_reset_id_{ … };
base::SequenceLocalStorageSlot<TracingSamplerProfiler>&
GetSequenceLocalStorageProfilerSlot() { … }
struct FrameDetails { … };
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) && defined(_WIN64) || \
ANDROID_ARM64_UNWINDING_SUPPORTED || ANDROID_CFI_UNWINDING_SUPPORTED || \
BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
bool IsStackSamplingSupported() { … }
#endif
perfetto::StaticString UnwinderTypeToString(
const TracingSamplerProfiler::UnwinderType unwinder_type) { … }
}
TracingSamplerProfiler::TracingProfileBuilder::BufferedSample::BufferedSample(
base::TimeTicks ts,
std::vector<base::Frame>&& s)
: … { … }
TracingSamplerProfiler::TracingProfileBuilder::BufferedSample::
~BufferedSample() = default;
TracingSamplerProfiler::TracingProfileBuilder::BufferedSample::BufferedSample(
TracingSamplerProfiler::TracingProfileBuilder::BufferedSample&& other)
: … { … }
TracingSamplerProfiler::TracingProfileBuilder::TracingProfileBuilder(
base::PlatformThreadId sampled_thread_id,
std::unique_ptr<perfetto::TraceWriterBase> trace_writer,
bool should_enable_filtering,
const base::RepeatingClosure& sample_callback_for_testing)
: … { … }
TracingSamplerProfiler::TracingProfileBuilder::~TracingProfileBuilder() { … }
base::ModuleCache*
TracingSamplerProfiler::TracingProfileBuilder::GetModuleCache() { … }
SampleDebugProto;
void TracingSamplerProfiler::TracingProfileBuilder::OnSampleCompleted(
std::vector<base::Frame> frames,
base::TimeTicks sample_timestamp) { … }
void TracingSamplerProfiler::TracingProfileBuilder::WriteSampleToTrace(
TracingSamplerProfiler::TracingProfileBuilder::BufferedSample sample) { … }
void TracingSamplerProfiler::TracingProfileBuilder::SetTraceWriter(
std::unique_ptr<perfetto::TraceWriterBase> writer) { … }
void TracingSamplerProfiler::TracingProfileBuilder::SetUnwinderType(
const TracingSamplerProfiler::UnwinderType unwinder_type) { … }
TracingSamplerProfiler::StackProfileWriter::StackProfileWriter(
bool enable_filtering)
: … { … }
TracingSamplerProfiler::StackProfileWriter::~StackProfileWriter() = default;
InterningID
TracingSamplerProfiler::StackProfileWriter::GetCallstackIDAndMaybeEmit(
std::vector<base::Frame>& frames,
perfetto::TraceWriter::TracePacketHandle* trace_packet) { … }
void TracingSamplerProfiler::StackProfileWriter::ResetEmittedState() { … }
std::unique_ptr<TracingSamplerProfiler>
TracingSamplerProfiler::CreateOnMainThread(
CoreUnwindersCallback core_unwinders_factory_function,
UnwinderType unwinder_type) { … }
void TracingSamplerProfiler::CreateOnChildThread() { … }
void TracingSamplerProfiler::CreateOnChildThreadWithCustomUnwinders(
CoreUnwindersCallback core_unwinders_factory_function) { … }
void TracingSamplerProfiler::DeleteOnChildThreadForTesting() { … }
void TracingSamplerProfiler::ResetDataSourceForTesting() { … }
void TracingSamplerProfiler::RegisterDataSource() { … }
bool TracingSamplerProfiler::IsStackUnwindingSupportedForTesting() { … }
void TracingSamplerProfiler::SetAuxUnwinderFactoryOnMainThread(
const base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>& factory) { … }
void TracingSamplerProfiler::StartTracingForTesting(
PerfettoProducer* producer) { … }
void TracingSamplerProfiler::SetupStartupTracingForTesting() { … }
void TracingSamplerProfiler::StopTracingForTesting() { … }
TracingSamplerProfiler::TracingSamplerProfiler(
base::SamplingProfilerThreadToken sampled_thread_token,
CoreUnwindersCallback core_unwinders_factory_function,
UnwinderType unwinder_type)
: … { … }
TracingSamplerProfiler::~TracingSamplerProfiler() { … }
void TracingSamplerProfiler::SetAuxUnwinderFactory(
const base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>& factory) { … }
void TracingSamplerProfiler::SetSampleCallbackForTesting(
const base::RepeatingClosure& sample_callback_for_testing) { … }
void TracingSamplerProfiler::StartTracing(
std::unique_ptr<perfetto::TraceWriterBase> trace_writer,
bool should_enable_filtering) { … }
void TracingSamplerProfiler::StopTracing() { … }
}
PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(
COMPONENT_EXPORT(TRACING_CPP),
tracing::TracingSamplerProfilerDataSource::DataSourceProxy);
std::unique_ptr<perfetto::TraceWriterBase>
tracing::TracingSamplerProfilerDataSource::CreateTraceWriter() { … }