// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/tracing/perfetto_platform.h" #include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/task/deferred_sequenced_task_runner.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/trace_event/trace_event.h" #include "base/tracing/perfetto_task_runner.h" #include "base/tracing_buildflags.h" #include "build/build_config.h" #include "third_party/perfetto/protos/perfetto/trace/track_event/process_descriptor.gen.h" #include "third_party/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.h" #if BUILDFLAG(IS_ANDROID) #include "base/android/build_info.h" #endif // BUILDFLAG(IS_ANDROID) #if !BUILDFLAG(IS_NACL) #include "third_party/perfetto/include/perfetto/ext/base/thread_task_runner.h" #endif namespace base { namespace tracing { namespace { constexpr char kProcessNamePrefix[] = "org.chromium-"; } // namespace PerfettoPlatform::PerfettoPlatform(TaskRunnerType task_runner_type) : task_runner_type_(task_runner_type), deferred_task_runner_(new DeferredSequencedTaskRunner()), thread_local_object_([](void* object) { delete static_cast(object); }) { ThreadIdNameManager::GetInstance()->AddObserver(this); } PerfettoPlatform::~PerfettoPlatform() { ThreadIdNameManager::GetInstance()->RemoveObserver(this); } void PerfettoPlatform::StartTaskRunner( scoped_refptr task_runner) { DCHECK_EQ(task_runner_type_, TaskRunnerType::kThreadPool); DCHECK(!did_start_task_runner_); deferred_task_runner_->StartWithTaskRunner(task_runner); did_start_task_runner_ = true; } SequencedTaskRunner* PerfettoPlatform::task_runner() const { return deferred_task_runner_.get(); } PerfettoPlatform::ThreadLocalObject* PerfettoPlatform::GetOrCreateThreadLocalObject() { auto* object = static_cast(thread_local_object_.Get()); if (!object) { object = ThreadLocalObject::CreateInstance().release(); thread_local_object_.Set(object); } return object; } std::unique_ptr PerfettoPlatform::CreateTaskRunner( const CreateTaskRunnerArgs&) { switch (task_runner_type_) { case TaskRunnerType::kBuiltin: #if !BUILDFLAG(IS_NACL) return std::make_unique( perfetto::base::ThreadTaskRunner::CreateAndStart()); #else DCHECK(false); return nullptr; #endif case TaskRunnerType::kThreadPool: // We can't create a real task runner yet because the ThreadPool may not // be initialized. Instead, we point Perfetto to a buffering task runner // which will become active as soon as the thread pool is up (see // StartTaskRunner). return std::make_unique(deferred_task_runner_); } } // This method is used by the SDK to determine the producer name. // Note that we override the producer name for the mojo backend in ProducerHost, // and thus this only affects the producer name for the system backend. std::string PerfettoPlatform::GetCurrentProcessName() { const char* host_package_name = nullptr; #if BUILDFLAG(IS_ANDROID) host_package_name = android::BuildInfo::GetInstance()->host_package_name(); #endif // BUILDFLAG(IS_ANDROID) // On Android we want to include if this is webview inside of an app or // Android Chrome. To aid this we add the host_package_name to differentiate // the various apps and sources. std::string process_name; if (host_package_name) { process_name = StrCat( {kProcessNamePrefix, host_package_name, "-", NumberToString(trace_event::TraceLog::GetInstance()->process_id())}); } else { process_name = StrCat( {kProcessNamePrefix, NumberToString(trace_event::TraceLog::GetInstance()->process_id())}); } return process_name; } void PerfettoPlatform::OnThreadNameChanged(const char* name) { #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) int process_id = trace_event::TraceLog::GetInstance()->process_id(); if (perfetto::Tracing::IsInitialized()) { auto track = perfetto::ThreadTrack::Current(); auto desc = track.Serialize(); desc.mutable_thread()->set_thread_name(name); desc.mutable_thread()->set_pid(process_id); perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc)); } #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) } } // namespace tracing } // namespace base