0

Reland "Reland "[tracing] Use trace thread for gpu process to initialize tracing""

This is a reland of commit 972bef57b3
No change was made. LUCI Bisection misdiagnosed this CL as the
culprit of ASAN failures.

Original change's description:
> Reland "[tracing] Use trace thread for gpu process to initialize tracing"
>
> This is a reland of commit 44d8036a9d
>
> Previous CL was reverted because PostDelayedTask is dropped when
> Linux/ChromeOS sandboxing procedure stops the running thread. Such tasks
> need to be reposted. There're several places that PostDelayedTask to the
> trace_thread:
> - Some are through the PerfettoTaskRunner, that can be tracked easily.
> - One is directly posted by ConnectProducerSocketViaMojo, needs to be
>   special treated.
>
> This CL:
> - For trace_startup.h/.cc, add option to start tracing using the
>   trace_thread, and set will_trace_thread_restart to true on linux and
>   chromeos.
> - For perfetto_traced_process.h/.cc, postpone system tracing producer
>   socket connection to after sandbox entrance on linux & chromeos.
> - For perfetto_task_runner.h/.cc, store delayed tasks and post them when
>   internal taks_runner is reset.
>
> Original change's description:
> > [tracing] Use trace thread for gpu process to initialize tracing
> >
> > For non-zygote child gpu thread, start the trace thread in
> > ContentMainRunnerImpl() directly.
> >
> > For zygote child gpu thread, start the trace thread in RunZygote after
> > zygote fork and featurelist init.
> >
> > For Linux & ChromeOS, stop and restart the trace thread when entering
> > sandbox. Restarting trace thread has a caveat that delayed tasks would
> > will be lost unless we save them.
> >
> > This is [3/?] CL of enabling tracing prior to sandboxing.
> >
> > Bug: 380411640
> > Change-Id: I89fa94f63a709de0e3da4f8759098c9fff813bee
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6180639
> > Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
> > Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
> > Commit-Queue: Kramer Ge <fangzhoug@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#1428704}
>
> Bug: 380411640, b/401194534
> Change-Id: I0f9172e48ee601f0236d84b0d8f784a11bd3d61a
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6462335
> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
> Commit-Queue: Kramer Ge <fangzhoug@chromium.org>
> Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
> Reviewed-by: Zhenyao Mo <zmo@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1451893}

Bug: 380411640, b/401194534
Change-Id: I32d42c00b0645783f00898ddc5167d655d773246
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6495650
Commit-Queue: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Auto-Submit: Kramer Ge <fangzhoug@chromium.org>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453740}
This commit is contained in:
Kramer Ge
2025-04-30 00:08:51 -07:00
committed by Chromium LUCI CQ
parent c1f8749737
commit a805bb0151
11 changed files with 171 additions and 56 deletions

@ -108,7 +108,7 @@ void ConnectProducerSocketViaMojo(perfetto::CreateSocketCallback cb,
// Wrapper for |ConnectProducerSocketViaMojo| to be used as a function pointer.
void ConnectProducerSocketAsync(perfetto::CreateSocketCallback cb) {
ConnectProducerSocketViaMojo(std::move(cb), base::Milliseconds(100));
PerfettoTracedProcess::Get().DeferOrConnectProducerSocket(std::move(cb));
}
#endif
@ -171,19 +171,22 @@ void PerfettoTracedProcess::DataSourceBase::ResetTaskRunner(
GetDataSourceTaskRunner() = task_runner;
}
// static
void PerfettoTracedProcess::RestartThreadInSandbox() {
base::Thread* trace_thread = PerfettoTracedProcess::GetTraceThread();
if (trace_thread->StartWithOptions(
base::Thread::Options(base::MessagePumpType::IO, 0))) {
DETACH_FROM_SEQUENCE(PerfettoTracedProcess::Get().sequence_checker_);
PerfettoTracedProcess::Get().task_runner_ = trace_thread->task_runner();
PerfettoTracedProcess::Get().platform_->ResetTaskRunner(
trace_thread->task_runner());
DataSourceBase::ResetTaskRunner(trace_thread->task_runner());
PerfettoTracedProcess::Get().tracing_backend_->DetachFromMuxerSequence();
CustomEventRecorder::GetInstance()->DetachFromSequence();
CHECK(trace_process_thread_->StartWithOptions(
base::Thread::Options(base::MessagePumpType::IO, 0)));
DETACH_FROM_SEQUENCE(sequence_checker_);
task_runner_ = trace_process_thread_->task_runner();
platform_->ResetTaskRunner(trace_process_thread_->task_runner());
DataSourceBase::ResetTaskRunner(trace_process_thread_->task_runner());
tracing_backend_->DetachFromMuxerSequence();
CustomEventRecorder::GetInstance()->DetachFromSequence();
will_trace_thread_restart_ = false;
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
if (system_tracing_producer_socket_cb_) {
task_runner_->PostTask(FROM_HERE,
std::move(system_tracing_producer_socket_cb_));
}
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
}
// static
@ -200,8 +203,10 @@ PerfettoTracedProcess& PerfettoTracedProcess::MaybeCreateInstance() {
}
// static
PerfettoTracedProcess& PerfettoTracedProcess::MaybeCreateInstanceWithThread() {
static base::NoDestructor<PerfettoTracedProcess> traced_process{};
PerfettoTracedProcess& PerfettoTracedProcess::MaybeCreateInstanceWithThread(
bool will_trace_thread_restart) {
static base::NoDestructor<PerfettoTracedProcess> traced_process(
will_trace_thread_restart);
return *traced_process;
}
@ -217,15 +222,18 @@ PerfettoTracedProcess& PerfettoTracedProcess::Get() {
return *g_instance;
}
PerfettoTracedProcess::PerfettoTracedProcess()
PerfettoTracedProcess::PerfettoTracedProcess(bool will_trace_thread_restart)
: trace_process_thread_(std::make_unique<base::Thread>("PerfettoTrace")),
task_runner_(trace_process_thread_->StartWithOptions(
base::Thread::Options(base::MessagePumpType::IO, 0))
? trace_process_thread_->task_runner()
: nullptr),
platform_(
std::make_unique<base::tracing::PerfettoPlatform>(task_runner_)),
will_trace_thread_restart_(will_trace_thread_restart),
tracing_backend_(std::make_unique<PerfettoTracingBackend>()) {
base::tracing::PerfettoPlatform::Options options{
.defer_delayed_tasks = will_trace_thread_restart_};
platform_ =
std::make_unique<base::tracing::PerfettoPlatform>(task_runner_, options);
DETACH_FROM_SEQUENCE(sequence_checker_);
CHECK_EQ(g_instance, nullptr);
CHECK(task_runner_);
@ -366,6 +374,20 @@ void PerfettoTracedProcess::SetupClientLibrary(bool enable_consumer) {
CustomEventRecorder::GetInstance();
}
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
void PerfettoTracedProcess::DeferOrConnectProducerSocket(
perfetto::CreateSocketCallback cb) {
CHECK(!system_tracing_producer_socket_cb_);
// Hold off the attempts to get socket fd until trace thread restarts.
if (will_trace_thread_restart_) {
system_tracing_producer_socket_cb_ = base::BindOnce(
ConnectProducerSocketViaMojo, cb, base::Milliseconds(100));
} else {
ConnectProducerSocketViaMojo(cb, base::Milliseconds(100));
}
}
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
void PerfettoTracedProcess::OnThreadPoolAvailable(bool enable_consumer) {
thread_pool_started_ = true;
SetupClientLibrary(enable_consumer);

@ -97,6 +97,9 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
// By default, data source callbacks (e.g., Start/StopTracingImpl) are
// called on PerfettoTracedProcess::GetTaskRunner()'s sequence. This method
// allows overriding that task runner.
// Note: The task_runner's thread may stop and restart for Linux/ChromeOS
// sandboxing so the task_runner can change and delayed tasks posted to it
// may be silently dropped.
virtual base::SequencedTaskRunner* GetTaskRunner();
static void ResetTaskRunner(
@ -152,8 +155,8 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
perfetto::DataSourceConfig data_source_config_;
};
// Restart the trace thread and replace the task_runner for tracing.
static void RestartThreadInSandbox();
// Restarts the trace thread and replaces the task_runner for tracing.
void RestartThreadInSandbox();
// Returns the process-wide ptr to the trace thread, returns nullptr if the
// task_runner for tracing is from the thread-pool.
@ -161,7 +164,8 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
// Creates the process-wide instance of the PerfettoTracedProcess.
static PerfettoTracedProcess& MaybeCreateInstance();
static PerfettoTracedProcess& MaybeCreateInstanceWithThread();
static PerfettoTracedProcess& MaybeCreateInstanceWithThread(
bool will_trace_thread_restart);
static PerfettoTracedProcess& MaybeCreateInstanceForTesting();
// Returns the process-wide instance of the PerfettoTracedProcess.
@ -228,11 +232,15 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
const perfetto::TraceConfig& config,
const perfetto::Tracing::SetupStartupTracingOpts& opts);
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
void DeferOrConnectProducerSocket(perfetto::CreateSocketCallback cb);
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
private:
friend class base::NoDestructor<PerfettoTracedProcess>;
// Default constructor would create a dedicated thread for tracing
PerfettoTracedProcess();
explicit PerfettoTracedProcess(bool will_trace_thread_restart);
explicit PerfettoTracedProcess(
scoped_refptr<base::SequencedTaskRunner> task_runner);
@ -261,6 +269,11 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
std::unique_ptr<base::Thread> trace_process_thread_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
bool will_trace_thread_restart_ = false;
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
base::OnceClosure system_tracing_producer_socket_cb_;
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
// Platform implementation for the Perfetto client library.
std::unique_ptr<base::tracing::PerfettoPlatform> platform_;
std::unique_ptr<PerfettoTracingBackend> tracing_backend_;

@ -46,17 +46,15 @@ using base::trace_event::TraceLog;
} // namespace
bool g_tracing_initialized_after_featurelist = false;
bool g_tracing_with_thread = false;
bool IsTracingInitialized() {
return g_tracing_initialized_after_featurelist;
}
void EnableStartupTracingIfNeeded() {
void EnableStartupTracingIfNeeded(bool with_thread) {
RegisterTracedValueProtoWriter();
// Create the PerfettoTracedProcess.
PerfettoTracedProcess::MaybeCreateInstance();
// Initialize the client library's TrackRegistry to support trace points
// during startup tracing. We don't setup the client library completely here
// yet, because we don't have field trials loaded yet (which influence which
@ -65,6 +63,20 @@ void EnableStartupTracingIfNeeded() {
// setting up the client library?
perfetto::internal::TrackRegistry::InitializeInstance();
// Create the PerfettoTracedProcess.
if (with_thread) {
g_tracing_with_thread = true;
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
PerfettoTracedProcess::MaybeCreateInstanceWithThread(
/*will_trace_thread_restart=*/true);
#else
PerfettoTracedProcess::MaybeCreateInstanceWithThread(
/*will_trace_thread_restart=*/false);
#endif
} else {
PerfettoTracedProcess::MaybeCreateInstance();
}
// Ensure TraceLog is initialized first.
// https://crbug.com/764357
TraceLog::GetInstance();
@ -105,7 +117,9 @@ void InitTracingPostFeatureList(bool enable_consumer) {
DCHECK(base::FeatureList::GetInstance());
// Create the PerfettoTracedProcess.
PerfettoTracedProcess::MaybeCreateInstance();
if (!g_tracing_with_thread) {
PerfettoTracedProcess::MaybeCreateInstance();
}
PerfettoTracedProcess::Get().OnThreadPoolAvailable(enable_consumer);
#if BUILDFLAG(IS_WIN)
tracing::EnableETWExport();

@ -35,7 +35,8 @@ bool COMPONENT_EXPORT(TRACING_CPP) IsTracingInitialized();
// TODO(eseckler): Consider allocating the SMB in parent processes outside the
// sandbox and supply it via the command line. Then, we can revert to call this
// earlier and from fewer places again.
void COMPONENT_EXPORT(TRACING_CPP) EnableStartupTracingIfNeeded();
void COMPONENT_EXPORT(TRACING_CPP)
EnableStartupTracingIfNeeded(bool with_thread = false);
// Enable startup tracing for the current process with the provided config. Sets
// up ProducerClient and trace event and/or sampler profiler data sources, and