Reland "Reland "[tracing] Use trace thread for gpu process to initialize tracing""
This is a reland of commit972bef57b3
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 commit44d8036a9d
> > 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:

committed by
Chromium LUCI CQ

parent
c1f8749737
commit
a805bb0151
base/tracing
content
services/tracing/public/cpp
ui/gl
@ -27,6 +27,7 @@ PerfettoPlatform::PerfettoPlatform(
|
|||||||
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
||||||
Options options)
|
Options options)
|
||||||
: process_name_prefix_(std::move(options.process_name_prefix)),
|
: process_name_prefix_(std::move(options.process_name_prefix)),
|
||||||
|
defer_delayed_tasks_(options.defer_delayed_tasks),
|
||||||
task_runner_(std::move(task_runner)),
|
task_runner_(std::move(task_runner)),
|
||||||
thread_local_object_([](void* object) {
|
thread_local_object_([](void* object) {
|
||||||
delete static_cast<ThreadLocalObject*>(object);
|
delete static_cast<ThreadLocalObject*>(object);
|
||||||
@ -49,7 +50,7 @@ std::unique_ptr<perfetto::base::TaskRunner> PerfettoPlatform::CreateTaskRunner(
|
|||||||
// TODO(b/242965112): Add support for the builtin task runner
|
// TODO(b/242965112): Add support for the builtin task runner
|
||||||
DCHECK(!perfetto_task_runner_);
|
DCHECK(!perfetto_task_runner_);
|
||||||
auto perfetto_task_runner =
|
auto perfetto_task_runner =
|
||||||
std::make_unique<PerfettoTaskRunner>(task_runner_);
|
std::make_unique<PerfettoTaskRunner>(task_runner_, defer_delayed_tasks_);
|
||||||
perfetto_task_runner_ = perfetto_task_runner->GetWeakPtr();
|
perfetto_task_runner_ = perfetto_task_runner->GetWeakPtr();
|
||||||
return perfetto_task_runner;
|
return perfetto_task_runner;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,10 @@ class BASE_EXPORT PerfettoPlatform : public perfetto::Platform {
|
|||||||
// TraceConfig.DataSource.producer_name_filter).
|
// TraceConfig.DataSource.producer_name_filter).
|
||||||
std::string process_name_prefix = "org.chromium-";
|
std::string process_name_prefix = "org.chromium-";
|
||||||
|
|
||||||
|
// Defer delayed tasks to PerfettoTaskRunner until task runner resets after
|
||||||
|
// sandbox entry.
|
||||||
|
bool defer_delayed_tasks = false;
|
||||||
|
|
||||||
// Work around https://bugs.llvm.org/show_bug.cgi?id=36684
|
// Work around https://bugs.llvm.org/show_bug.cgi?id=36684
|
||||||
static Options Default() { return {}; }
|
static Options Default() { return {}; }
|
||||||
};
|
};
|
||||||
@ -50,6 +54,7 @@ class BASE_EXPORT PerfettoPlatform : public perfetto::Platform {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string process_name_prefix_;
|
const std::string process_name_prefix_;
|
||||||
|
const bool defer_delayed_tasks_;
|
||||||
WeakPtr<PerfettoTaskRunner> perfetto_task_runner_;
|
WeakPtr<PerfettoTaskRunner> perfetto_task_runner_;
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||||
ThreadLocalStorage::Slot thread_local_object_;
|
ThreadLocalStorage::Slot thread_local_object_;
|
||||||
|
@ -22,8 +22,10 @@
|
|||||||
namespace base::tracing {
|
namespace base::tracing {
|
||||||
|
|
||||||
PerfettoTaskRunner::PerfettoTaskRunner(
|
PerfettoTaskRunner::PerfettoTaskRunner(
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner)
|
scoped_refptr<base::SequencedTaskRunner> task_runner,
|
||||||
: task_runner_(std::move(task_runner)) {
|
bool defer_delayed_tasks)
|
||||||
|
: task_runner_(std::move(task_runner)),
|
||||||
|
defer_delayed_tasks_(defer_delayed_tasks) {
|
||||||
CHECK(task_runner_);
|
CHECK(task_runner_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,6 +42,10 @@ void PerfettoTaskRunner::PostTask(std::function<void()> task) {
|
|||||||
|
|
||||||
void PerfettoTaskRunner::PostDelayedTask(std::function<void()> task,
|
void PerfettoTaskRunner::PostDelayedTask(std::function<void()> task,
|
||||||
uint32_t delay_ms) {
|
uint32_t delay_ms) {
|
||||||
|
if (defer_delayed_tasks_ && delay_ms) {
|
||||||
|
deferred_delayed_tasks_.emplace_back(task, delay_ms);
|
||||||
|
return;
|
||||||
|
}
|
||||||
base::ScopedDeferTaskPosting::PostOrDefer(
|
base::ScopedDeferTaskPosting::PostOrDefer(
|
||||||
task_runner_, FROM_HERE,
|
task_runner_, FROM_HERE,
|
||||||
base::BindOnce(
|
base::BindOnce(
|
||||||
@ -117,6 +123,11 @@ void PerfettoTaskRunner::RemoveFileDescriptorWatch(
|
|||||||
void PerfettoTaskRunner::ResetTaskRunner(
|
void PerfettoTaskRunner::ResetTaskRunner(
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner) {
|
scoped_refptr<base::SequencedTaskRunner> task_runner) {
|
||||||
task_runner_ = std::move(task_runner);
|
task_runner_ = std::move(task_runner);
|
||||||
|
defer_delayed_tasks_ = false;
|
||||||
|
for (auto& task : deferred_delayed_tasks_) {
|
||||||
|
PostDelayedTask(task.task, task.delay);
|
||||||
|
}
|
||||||
|
deferred_delayed_tasks_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
|
#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
|
||||||
@ -127,4 +138,12 @@ PerfettoTaskRunner::FDControllerAndCallback::~FDControllerAndCallback() =
|
|||||||
default;
|
default;
|
||||||
#endif // (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
|
#endif // (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
|
||||||
|
|
||||||
|
PerfettoTaskRunner::DeferredTask::DeferredTask(std::function<void()> task,
|
||||||
|
uint32_t delay)
|
||||||
|
: task(std::move(task)), delay(delay) {}
|
||||||
|
|
||||||
|
PerfettoTaskRunner::DeferredTask::DeferredTask(DeferredTask&& task) = default;
|
||||||
|
|
||||||
|
PerfettoTaskRunner::DeferredTask::~DeferredTask() = default;
|
||||||
|
|
||||||
} // namespace base::tracing
|
} // namespace base::tracing
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#ifndef BASE_TRACING_PERFETTO_TASK_RUNNER_H_
|
#ifndef BASE_TRACING_PERFETTO_TASK_RUNNER_H_
|
||||||
#define BASE_TRACING_PERFETTO_TASK_RUNNER_H_
|
#define BASE_TRACING_PERFETTO_TASK_RUNNER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "base/base_export.h"
|
#include "base/base_export.h"
|
||||||
#include "base/cancelable_callback.h"
|
#include "base/cancelable_callback.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
@ -29,7 +31,8 @@ namespace tracing {
|
|||||||
// to provide it to Perfetto.
|
// to provide it to Perfetto.
|
||||||
class BASE_EXPORT PerfettoTaskRunner : public perfetto::base::TaskRunner {
|
class BASE_EXPORT PerfettoTaskRunner : public perfetto::base::TaskRunner {
|
||||||
public:
|
public:
|
||||||
explicit PerfettoTaskRunner(scoped_refptr<base::SequencedTaskRunner>);
|
explicit PerfettoTaskRunner(scoped_refptr<base::SequencedTaskRunner>,
|
||||||
|
bool defer_delayed_tasks = false);
|
||||||
~PerfettoTaskRunner() override;
|
~PerfettoTaskRunner() override;
|
||||||
PerfettoTaskRunner(const PerfettoTaskRunner&) = delete;
|
PerfettoTaskRunner(const PerfettoTaskRunner&) = delete;
|
||||||
void operator=(const PerfettoTaskRunner&) = delete;
|
void operator=(const PerfettoTaskRunner&) = delete;
|
||||||
@ -58,6 +61,21 @@ class BASE_EXPORT PerfettoTaskRunner : public perfetto::base::TaskRunner {
|
|||||||
private:
|
private:
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
||||||
|
|
||||||
|
struct DeferredTask {
|
||||||
|
DeferredTask(std::function<void()> task, uint32_t delay);
|
||||||
|
DeferredTask(const DeferredTask&) = delete;
|
||||||
|
DeferredTask& operator=(const DeferredTask&) = delete;
|
||||||
|
DeferredTask(DeferredTask&& task);
|
||||||
|
~DeferredTask();
|
||||||
|
|
||||||
|
std::function<void()> task;
|
||||||
|
uint32_t delay;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delayed tasks will be posted when `task_runner_` resets.
|
||||||
|
std::vector<DeferredTask> deferred_delayed_tasks_;
|
||||||
|
bool defer_delayed_tasks_;
|
||||||
|
|
||||||
#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
|
#if (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_NACL)) || BUILDFLAG(IS_FUCHSIA)
|
||||||
// FDControllerAndCallback keeps track of the state of FD watching:
|
// FDControllerAndCallback keeps track of the state of FD watching:
|
||||||
// * |controller| has value: FD watching is added. |callback| is nullopt.
|
// * |controller| has value: FD watching is added. |callback| is nullopt.
|
||||||
|
@ -662,7 +662,18 @@ NO_STACK_PROTECTOR int RunZygote(ContentMainDelegate* delegate) {
|
|||||||
|
|
||||||
MainFunctionParams main_params(command_line);
|
MainFunctionParams main_params(command_line);
|
||||||
main_params.zygote_child = true;
|
main_params.zygote_child = true;
|
||||||
main_params.needs_startup_tracing_after_mojo_init = true;
|
|
||||||
|
if (process_type == switches::kGpuProcess) {
|
||||||
|
// Once Zygote forks and feature list initializes we can start a thread to
|
||||||
|
// begin tracing immediately.
|
||||||
|
// TODO(https://crbug.com/380411640): Enable for more processes other than
|
||||||
|
// GPU process.
|
||||||
|
tracing::EnableStartupTracingIfNeeded(/*with_thread=*/true);
|
||||||
|
tracing::InitTracingPostFeatureList(/*enable_consumer=*/false);
|
||||||
|
main_params.needs_startup_tracing_after_mojo_init = false;
|
||||||
|
} else {
|
||||||
|
main_params.needs_startup_tracing_after_mojo_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
// The hang watcher needs to be created once the feature list is available
|
// The hang watcher needs to be created once the feature list is available
|
||||||
// but before the IO thread is started.
|
// but before the IO thread is started.
|
||||||
@ -892,15 +903,27 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
|
|||||||
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
||||||
// A sandboxed process won't be able to allocate the SMB needed for startup
|
// A sandboxed process won't be able to allocate the SMB needed for startup
|
||||||
// tracing until Mojo IPC support is brought up, at which point the Mojo
|
// tracing until Mojo IPC support is brought up, at which point the Mojo
|
||||||
// broker will transparently broker the SMB creation.
|
// broker will transparently broker the SMB creation. Unless the sandboxed
|
||||||
if (!sandbox::policy::IsUnsandboxedSandboxType(
|
// process stops the trace threads when entering sandbox.
|
||||||
|
// TODO(https://crbug.com/380411640): Implement for other processes other than
|
||||||
|
// GPU process.
|
||||||
|
if (process_type != switches::kGpuProcess &&
|
||||||
|
!sandbox::policy::IsUnsandboxedSandboxType(
|
||||||
sandbox::policy::SandboxTypeFromCommandLine(command_line))) {
|
sandbox::policy::SandboxTypeFromCommandLine(command_line))) {
|
||||||
enable_startup_tracing = false;
|
enable_startup_tracing = false;
|
||||||
needs_startup_tracing_after_mojo_init_ = true;
|
needs_startup_tracing_after_mojo_init_ = true;
|
||||||
}
|
}
|
||||||
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_MAC)
|
||||||
if (enable_startup_tracing) {
|
if (enable_startup_tracing) {
|
||||||
tracing::EnableStartupTracingIfNeeded();
|
if (process_type == switches::kGpuProcess) {
|
||||||
|
// Without Zygote and posix sandbox we can start a thread to begin tracing
|
||||||
|
// immediately.
|
||||||
|
// TODO(https://crbug.com/380411640): Enable for more processes other than
|
||||||
|
// GPU process.
|
||||||
|
tracing::EnableStartupTracingIfNeeded(/*with_thread=*/true);
|
||||||
|
} else {
|
||||||
|
tracing::EnableStartupTracingIfNeeded(/*with_thread=*/false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize");
|
TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize");
|
||||||
|
|
||||||
@ -1116,6 +1139,9 @@ NO_STACK_PROTECTOR int ContentMainRunnerImpl::Run() {
|
|||||||
ContentMainDelegate::InvokedInChildProcess())) {
|
ContentMainDelegate::InvokedInChildProcess())) {
|
||||||
InitializeFieldTrialAndFeatureList();
|
InitializeFieldTrialAndFeatureList();
|
||||||
}
|
}
|
||||||
|
if (process_type == switches::kGpuProcess) {
|
||||||
|
tracing::InitTracingPostFeatureList(/*enable_consumer=*/false);
|
||||||
|
}
|
||||||
if (delegate_->ShouldInitializeMojo(
|
if (delegate_->ShouldInitializeMojo(
|
||||||
ContentMainDelegate::InvokedInChildProcess())) {
|
ContentMainDelegate::InvokedInChildProcess())) {
|
||||||
InitializeMojoCore();
|
InitializeMojoCore();
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "base/task/single_thread_task_executor.h"
|
#include "base/task/single_thread_task_executor.h"
|
||||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||||
#include "base/threading/platform_thread.h"
|
#include "base/threading/platform_thread.h"
|
||||||
|
#include "base/threading/thread.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/timer/hi_res_timer_manager.h"
|
#include "base/timer/hi_res_timer_manager.h"
|
||||||
#include "base/trace_event/trace_event.h"
|
#include "base/trace_event/trace_event.h"
|
||||||
@ -44,6 +45,7 @@
|
|||||||
#include "content/public/common/content_switches.h"
|
#include "content/public/common/content_switches.h"
|
||||||
#include "content/public/common/main_function_params.h"
|
#include "content/public/common/main_function_params.h"
|
||||||
#include "content/public/common/result_codes.h"
|
#include "content/public/common/result_codes.h"
|
||||||
|
#include "content/public/common/zygote/zygote_buildflags.h"
|
||||||
#include "content/public/gpu/content_gpu_client.h"
|
#include "content/public/gpu/content_gpu_client.h"
|
||||||
#include "gpu/command_buffer/service/gpu_switches.h"
|
#include "gpu/command_buffer/service/gpu_switches.h"
|
||||||
#include "gpu/config/gpu_driver_bug_list.h"
|
#include "gpu/config/gpu_driver_bug_list.h"
|
||||||
@ -59,6 +61,7 @@
|
|||||||
#include "media/gpu/buildflags.h"
|
#include "media/gpu/buildflags.h"
|
||||||
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
#include "mojo/public/cpp/bindings/interface_endpoint_client.h"
|
||||||
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
|
||||||
|
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
|
||||||
#include "services/tracing/public/cpp/trace_startup.h"
|
#include "services/tracing/public/cpp/trace_startup.h"
|
||||||
#include "services/tracing/public/cpp/trace_startup_config.h"
|
#include "services/tracing/public/cpp/trace_startup_config.h"
|
||||||
#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
|
#include "third_party/angle/src/gpu_info_util/SystemInfo.h"
|
||||||
@ -196,11 +199,8 @@ class ContentSandboxHelper : public gpu::GpuSandboxHelper {
|
|||||||
|
|
||||||
// Main function for starting the Gpu process.
|
// Main function for starting the Gpu process.
|
||||||
int GpuMain(MainFunctionParams parameters) {
|
int GpuMain(MainFunctionParams parameters) {
|
||||||
if (tracing::TraceStartupConfig::GetInstance().IsEnabled()) {
|
TRACE_EVENT("gpu,startup", "GpuMain");
|
||||||
gl::StartupTrace::Startup();
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE_EVENT0("gpu", "GpuMain");
|
|
||||||
base::CurrentProcess::GetInstance().SetProcessType(
|
base::CurrentProcess::GetInstance().SetProcessType(
|
||||||
base::CurrentProcessType::PROCESS_GPU);
|
base::CurrentProcessType::PROCESS_GPU);
|
||||||
|
|
||||||
@ -310,7 +310,6 @@ int GpuMain(MainFunctionParams parameters) {
|
|||||||
base::MessagePumpType::DEFAULT);
|
base::MessagePumpType::DEFAULT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
gl::StartupTrace::GetInstance()->BindToCurrentThread();
|
|
||||||
|
|
||||||
base::PlatformThread::SetName("CrGpuMain");
|
base::PlatformThread::SetName("CrGpuMain");
|
||||||
mojo::InterfaceEndpointClient::SetThreadNameSuffixForMetrics("GpuMain");
|
mojo::InterfaceEndpointClient::SetThreadNameSuffixForMetrics("GpuMain");
|
||||||
@ -436,7 +435,6 @@ int GpuMain(MainFunctionParams parameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DCHECK(tracing::IsTracingInitialized());
|
DCHECK(tracing::IsTracingInitialized());
|
||||||
gl::StartupTrace::StarupDone();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
TRACE_EVENT0("gpu", "Run Message Loop");
|
TRACE_EVENT0("gpu", "Run Message Loop");
|
||||||
@ -460,6 +458,14 @@ bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
|
|||||||
sandbox::policy::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
|
sandbox::policy::SandboxLinux::GetInstance()->StopThread(watchdog_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::Thread* trace_thread =
|
||||||
|
tracing::IsTracingInitialized()
|
||||||
|
? tracing::PerfettoTracedProcess::GetTraceThread()
|
||||||
|
: nullptr;
|
||||||
|
if (trace_thread) {
|
||||||
|
sandbox::policy::SandboxLinux::GetInstance()->StopThread(trace_thread);
|
||||||
|
}
|
||||||
|
|
||||||
// SandboxLinux::InitializeSandbox() must always be called
|
// SandboxLinux::InitializeSandbox() must always be called
|
||||||
// with only one thread.
|
// with only one thread.
|
||||||
sandbox::policy::SandboxLinux::Options sandbox_options;
|
sandbox::policy::SandboxLinux::Options sandbox_options;
|
||||||
@ -509,6 +515,10 @@ bool StartSandboxLinux(gpu::GpuWatchdogThread* watchdog_thread,
|
|||||||
watchdog_thread->Start();
|
watchdog_thread->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trace_thread) {
|
||||||
|
tracing::PerfettoTracedProcess::Get().RestartThreadInSandbox();
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||||
|
@ -108,7 +108,7 @@ void ConnectProducerSocketViaMojo(perfetto::CreateSocketCallback cb,
|
|||||||
|
|
||||||
// Wrapper for |ConnectProducerSocketViaMojo| to be used as a function pointer.
|
// Wrapper for |ConnectProducerSocketViaMojo| to be used as a function pointer.
|
||||||
void ConnectProducerSocketAsync(perfetto::CreateSocketCallback cb) {
|
void ConnectProducerSocketAsync(perfetto::CreateSocketCallback cb) {
|
||||||
ConnectProducerSocketViaMojo(std::move(cb), base::Milliseconds(100));
|
PerfettoTracedProcess::Get().DeferOrConnectProducerSocket(std::move(cb));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -171,19 +171,22 @@ void PerfettoTracedProcess::DataSourceBase::ResetTaskRunner(
|
|||||||
GetDataSourceTaskRunner() = task_runner;
|
GetDataSourceTaskRunner() = task_runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
|
||||||
void PerfettoTracedProcess::RestartThreadInSandbox() {
|
void PerfettoTracedProcess::RestartThreadInSandbox() {
|
||||||
base::Thread* trace_thread = PerfettoTracedProcess::GetTraceThread();
|
CHECK(trace_process_thread_->StartWithOptions(
|
||||||
if (trace_thread->StartWithOptions(
|
base::Thread::Options(base::MessagePumpType::IO, 0)));
|
||||||
base::Thread::Options(base::MessagePumpType::IO, 0))) {
|
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||||
DETACH_FROM_SEQUENCE(PerfettoTracedProcess::Get().sequence_checker_);
|
task_runner_ = trace_process_thread_->task_runner();
|
||||||
PerfettoTracedProcess::Get().task_runner_ = trace_thread->task_runner();
|
platform_->ResetTaskRunner(trace_process_thread_->task_runner());
|
||||||
PerfettoTracedProcess::Get().platform_->ResetTaskRunner(
|
DataSourceBase::ResetTaskRunner(trace_process_thread_->task_runner());
|
||||||
trace_thread->task_runner());
|
tracing_backend_->DetachFromMuxerSequence();
|
||||||
DataSourceBase::ResetTaskRunner(trace_thread->task_runner());
|
CustomEventRecorder::GetInstance()->DetachFromSequence();
|
||||||
PerfettoTracedProcess::Get().tracing_backend_->DetachFromMuxerSequence();
|
will_trace_thread_restart_ = false;
|
||||||
CustomEventRecorder::GetInstance()->DetachFromSequence();
|
#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
|
// static
|
||||||
@ -200,8 +203,10 @@ PerfettoTracedProcess& PerfettoTracedProcess::MaybeCreateInstance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
PerfettoTracedProcess& PerfettoTracedProcess::MaybeCreateInstanceWithThread() {
|
PerfettoTracedProcess& PerfettoTracedProcess::MaybeCreateInstanceWithThread(
|
||||||
static base::NoDestructor<PerfettoTracedProcess> traced_process{};
|
bool will_trace_thread_restart) {
|
||||||
|
static base::NoDestructor<PerfettoTracedProcess> traced_process(
|
||||||
|
will_trace_thread_restart);
|
||||||
return *traced_process;
|
return *traced_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,15 +222,18 @@ PerfettoTracedProcess& PerfettoTracedProcess::Get() {
|
|||||||
return *g_instance;
|
return *g_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerfettoTracedProcess::PerfettoTracedProcess()
|
PerfettoTracedProcess::PerfettoTracedProcess(bool will_trace_thread_restart)
|
||||||
: trace_process_thread_(std::make_unique<base::Thread>("PerfettoTrace")),
|
: trace_process_thread_(std::make_unique<base::Thread>("PerfettoTrace")),
|
||||||
task_runner_(trace_process_thread_->StartWithOptions(
|
task_runner_(trace_process_thread_->StartWithOptions(
|
||||||
base::Thread::Options(base::MessagePumpType::IO, 0))
|
base::Thread::Options(base::MessagePumpType::IO, 0))
|
||||||
? trace_process_thread_->task_runner()
|
? trace_process_thread_->task_runner()
|
||||||
: nullptr),
|
: nullptr),
|
||||||
platform_(
|
will_trace_thread_restart_(will_trace_thread_restart),
|
||||||
std::make_unique<base::tracing::PerfettoPlatform>(task_runner_)),
|
|
||||||
tracing_backend_(std::make_unique<PerfettoTracingBackend>()) {
|
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_);
|
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||||
CHECK_EQ(g_instance, nullptr);
|
CHECK_EQ(g_instance, nullptr);
|
||||||
CHECK(task_runner_);
|
CHECK(task_runner_);
|
||||||
@ -366,6 +374,20 @@ void PerfettoTracedProcess::SetupClientLibrary(bool enable_consumer) {
|
|||||||
CustomEventRecorder::GetInstance();
|
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) {
|
void PerfettoTracedProcess::OnThreadPoolAvailable(bool enable_consumer) {
|
||||||
thread_pool_started_ = true;
|
thread_pool_started_ = true;
|
||||||
SetupClientLibrary(enable_consumer);
|
SetupClientLibrary(enable_consumer);
|
||||||
|
@ -97,6 +97,9 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
|
|||||||
// By default, data source callbacks (e.g., Start/StopTracingImpl) are
|
// By default, data source callbacks (e.g., Start/StopTracingImpl) are
|
||||||
// called on PerfettoTracedProcess::GetTaskRunner()'s sequence. This method
|
// called on PerfettoTracedProcess::GetTaskRunner()'s sequence. This method
|
||||||
// allows overriding that task runner.
|
// 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();
|
virtual base::SequencedTaskRunner* GetTaskRunner();
|
||||||
|
|
||||||
static void ResetTaskRunner(
|
static void ResetTaskRunner(
|
||||||
@ -152,8 +155,8 @@ class COMPONENT_EXPORT(TRACING_CPP) PerfettoTracedProcess final
|
|||||||
perfetto::DataSourceConfig data_source_config_;
|
perfetto::DataSourceConfig data_source_config_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Restart the trace thread and replace the task_runner for tracing.
|
// Restarts the trace thread and replaces the task_runner for tracing.
|
||||||
static void RestartThreadInSandbox();
|
void RestartThreadInSandbox();
|
||||||
|
|
||||||
// Returns the process-wide ptr to the trace thread, returns nullptr if the
|
// Returns the process-wide ptr to the trace thread, returns nullptr if the
|
||||||
// task_runner for tracing is from the thread-pool.
|
// 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.
|
// Creates the process-wide instance of the PerfettoTracedProcess.
|
||||||
static PerfettoTracedProcess& MaybeCreateInstance();
|
static PerfettoTracedProcess& MaybeCreateInstance();
|
||||||
static PerfettoTracedProcess& MaybeCreateInstanceWithThread();
|
static PerfettoTracedProcess& MaybeCreateInstanceWithThread(
|
||||||
|
bool will_trace_thread_restart);
|
||||||
static PerfettoTracedProcess& MaybeCreateInstanceForTesting();
|
static PerfettoTracedProcess& MaybeCreateInstanceForTesting();
|
||||||
|
|
||||||
// Returns the process-wide instance of the PerfettoTracedProcess.
|
// 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::TraceConfig& config,
|
||||||
const perfetto::Tracing::SetupStartupTracingOpts& opts);
|
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:
|
private:
|
||||||
friend class base::NoDestructor<PerfettoTracedProcess>;
|
friend class base::NoDestructor<PerfettoTracedProcess>;
|
||||||
|
|
||||||
// Default constructor would create a dedicated thread for tracing
|
// Default constructor would create a dedicated thread for tracing
|
||||||
PerfettoTracedProcess();
|
explicit PerfettoTracedProcess(bool will_trace_thread_restart);
|
||||||
explicit PerfettoTracedProcess(
|
explicit PerfettoTracedProcess(
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner);
|
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_;
|
std::unique_ptr<base::Thread> trace_process_thread_;
|
||||||
scoped_refptr<base::SequencedTaskRunner> task_runner_;
|
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.
|
// Platform implementation for the Perfetto client library.
|
||||||
std::unique_ptr<base::tracing::PerfettoPlatform> platform_;
|
std::unique_ptr<base::tracing::PerfettoPlatform> platform_;
|
||||||
std::unique_ptr<PerfettoTracingBackend> tracing_backend_;
|
std::unique_ptr<PerfettoTracingBackend> tracing_backend_;
|
||||||
|
@ -46,17 +46,15 @@ using base::trace_event::TraceLog;
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool g_tracing_initialized_after_featurelist = false;
|
bool g_tracing_initialized_after_featurelist = false;
|
||||||
|
bool g_tracing_with_thread = false;
|
||||||
|
|
||||||
bool IsTracingInitialized() {
|
bool IsTracingInitialized() {
|
||||||
return g_tracing_initialized_after_featurelist;
|
return g_tracing_initialized_after_featurelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnableStartupTracingIfNeeded() {
|
void EnableStartupTracingIfNeeded(bool with_thread) {
|
||||||
RegisterTracedValueProtoWriter();
|
RegisterTracedValueProtoWriter();
|
||||||
|
|
||||||
// Create the PerfettoTracedProcess.
|
|
||||||
PerfettoTracedProcess::MaybeCreateInstance();
|
|
||||||
|
|
||||||
// Initialize the client library's TrackRegistry to support trace points
|
// Initialize the client library's TrackRegistry to support trace points
|
||||||
// during startup tracing. We don't setup the client library completely here
|
// 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
|
// yet, because we don't have field trials loaded yet (which influence which
|
||||||
@ -65,6 +63,20 @@ void EnableStartupTracingIfNeeded() {
|
|||||||
// setting up the client library?
|
// setting up the client library?
|
||||||
perfetto::internal::TrackRegistry::InitializeInstance();
|
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.
|
// Ensure TraceLog is initialized first.
|
||||||
// https://crbug.com/764357
|
// https://crbug.com/764357
|
||||||
TraceLog::GetInstance();
|
TraceLog::GetInstance();
|
||||||
@ -105,7 +117,9 @@ void InitTracingPostFeatureList(bool enable_consumer) {
|
|||||||
DCHECK(base::FeatureList::GetInstance());
|
DCHECK(base::FeatureList::GetInstance());
|
||||||
|
|
||||||
// Create the PerfettoTracedProcess.
|
// Create the PerfettoTracedProcess.
|
||||||
PerfettoTracedProcess::MaybeCreateInstance();
|
if (!g_tracing_with_thread) {
|
||||||
|
PerfettoTracedProcess::MaybeCreateInstance();
|
||||||
|
}
|
||||||
PerfettoTracedProcess::Get().OnThreadPoolAvailable(enable_consumer);
|
PerfettoTracedProcess::Get().OnThreadPoolAvailable(enable_consumer);
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
tracing::EnableETWExport();
|
tracing::EnableETWExport();
|
||||||
|
@ -35,7 +35,8 @@ bool COMPONENT_EXPORT(TRACING_CPP) IsTracingInitialized();
|
|||||||
// TODO(eseckler): Consider allocating the SMB in parent processes outside the
|
// 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
|
// sandbox and supply it via the command line. Then, we can revert to call this
|
||||||
// earlier and from fewer places again.
|
// 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
|
// Enable startup tracing for the current process with the provided config. Sets
|
||||||
// up ProducerClient and trace event and/or sampler profiler data sources, and
|
// up ProducerClient and trace event and/or sampler profiler data sources, and
|
||||||
|
@ -77,20 +77,6 @@ class GL_EXPORT StartupTrace {
|
|||||||
|
|
||||||
} // namespace gl
|
} // namespace gl
|
||||||
|
|
||||||
// Generate a unique variable name with a given prefix.
|
#define GPU_STARTUP_TRACE_EVENT(name) TRACE_EVENT("gpu,startup", name);
|
||||||
#define GPU_STARTUP_TRACE_INTERNAL_CONCAT2(a, b) a##b
|
|
||||||
#define GPU_STARTUP_TRACE_INTERNAL_CONCAT(a, b) \
|
|
||||||
GPU_STARTUP_TRACE_INTERNAL_CONCAT2(a, b)
|
|
||||||
#define GPU_STARTUP_TRACE_UID(prefix) \
|
|
||||||
GPU_STARTUP_TRACE_INTERNAL_CONCAT(prefix, __LINE__)
|
|
||||||
|
|
||||||
#define GPU_STARTUP_TRACE_EVENT(name) \
|
|
||||||
gl::StartupTrace::ScopedStage GPU_STARTUP_TRACE_UID(scoped_gpu_trace){0}; \
|
|
||||||
if (gl::StartupTrace::IsEnabled()) { \
|
|
||||||
GPU_STARTUP_TRACE_UID(scoped_gpu_trace) = \
|
|
||||||
gl::StartupTrace::GetInstance()->AddStage(name); \
|
|
||||||
} else { \
|
|
||||||
TRACE_EVENT0("gpu,startup", name); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // UI_GL_STARTUP_TRACE_H_
|
#endif // UI_GL_STARTUP_TRACE_H_
|
||||||
|
Reference in New Issue
Block a user