chromium/services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_APPLE)
#define INITIALIZE_THREAD_DELEGATE_POSIX
#endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_APPLE)

#if ANDROID_ARM64_UNWINDING_SUPPORTED || ANDROID_CFI_UNWINDING_SUPPORTED
#include <dlfcn.h>
#include "base/debug/elf_reader.h"
#endif  // ANDROID_ARM64_UNWINDING_SUPPORTED || ANDROID_CFI_UNWINDING_SUPPORTED

#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" {

// The address of |__executable_start| gives the start address of the
// executable or shared library. This value is used to find the offset address
// of the instruction in binary from PC.
extern char __executable_start;

}  // extern "C"

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  // ANDROID_ARM64_UNWINDING_SUPPORTED || ANDROID_CFI_UNWINDING_SUPPORTED

// Pointer to the main thread instance, if any.
TracingSamplerProfiler* g_main_thread_instance =;

class TracingSamplerProfilerDataSource;

TracingSamplerProfilerDataSource* g_sampler_profiler_ds_for_test =;

class TracingSamplerProfilerDataSource
    : public PerfettoTracedProcess::DataSourceBase {};

DataSourceProxy;

// static
std::atomic<uint32_t>
    TracingSamplerProfilerDataSource::incremental_state_reset_id_{};

base::SequenceLocalStorageSlot<TracingSamplerProfiler>&
GetSequenceLocalStorageProfilerSlot() {}

// Stores information about the StackFrame, to emit to the trace.
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)
// Returns whether stack sampling is supported on the current platform.
bool IsStackSamplingSupported() {}
#endif

perfetto::StaticString UnwinderTypeToString(
    const TracingSamplerProfiler::UnwinderType unwinder_type) {}

}  // namespace

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() {}

// static
std::unique_ptr<TracingSamplerProfiler>
TracingSamplerProfiler::CreateOnMainThread(
    CoreUnwindersCallback core_unwinders_factory_function,
    UnwinderType unwinder_type) {}

// static
void TracingSamplerProfiler::CreateOnChildThread() {}

// static
void TracingSamplerProfiler::CreateOnChildThreadWithCustomUnwinders(
    CoreUnwindersCallback core_unwinders_factory_function) {}

// static
void TracingSamplerProfiler::DeleteOnChildThreadForTesting() {}

// static
void TracingSamplerProfiler::ResetDataSourceForTesting() {}

// static
void TracingSamplerProfiler::RegisterDataSource() {}

// static
bool TracingSamplerProfiler::IsStackUnwindingSupportedForTesting() {}

void TracingSamplerProfiler::SetAuxUnwinderFactoryOnMainThread(
    const base::RepeatingCallback<std::unique_ptr<base::Unwinder>()>& factory) {}

// TODO(b/336718643): Remove unused code after removing use_perfetto_client_library build
// flag.
// static
void TracingSamplerProfiler::StartTracingForTesting(
    PerfettoProducer* producer) {}

// static
void TracingSamplerProfiler::SetupStartupTracingForTesting() {}

// static
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() {}

}  // namespace tracing

PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(
    COMPONENT_EXPORT(TRACING_CPP),
    tracing::TracingSamplerProfilerDataSource::DataSourceProxy);

// This should go after PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS
// to avoid instantiation of type() template method before specialization.
std::unique_ptr<perfetto::TraceWriterBase>
tracing::TracingSamplerProfilerDataSource::CreateTraceWriter() {}