Commit fc975678 authored by Alexander Timin's avatar Alexander Timin Committed by Chromium LUCI CQ

[tracing] StartupTracingController

Refactor startup tracing logic out of TracingControllerImpl and use
modern TracingSession from Perfetto client API directly.

This allows for much greater simplification, including removing
substantial amount of logic from TracingControllerImpl (including
logic for finishing trace recording after a timeout) and removing
PerfettoFileTracer.

This also allows for a clean implementation of features like streaming
trace to a file and merging browsertest and startup tracing logic.

R=eseckler@chromium.org,skyostil@chromium.org
BUG=1157954,1082916

Change-Id: Id4c608b05cbd6b0696cb8e3445888b6a9d86c797
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2587040
Commit-Queue: Alexander Timin <altimin@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Reviewed-by: default avatarEric Seckler <eseckler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839190}
parent 78eb032e
...@@ -83,7 +83,7 @@ TraceStartupConfig::TraceStartupConfig() { ...@@ -83,7 +83,7 @@ TraceStartupConfig::TraceStartupConfig() {
if (EnableFromCommandLine()) { if (EnableFromCommandLine()) {
DCHECK(IsEnabled()); DCHECK(IsEnabled());
} else if (EnableFromConfigFile()) { } else if (EnableFromConfigFile()) {
DCHECK(IsEnabled() || IsUsingPerfettoOutput()); DCHECK(IsEnabled());
} else if (EnableFromBackgroundTracing()) { } else if (EnableFromBackgroundTracing()) {
DCHECK(IsEnabled()); DCHECK(IsEnabled());
DCHECK(!IsTracingStartupForDuration()); DCHECK(!IsTracingStartupForDuration());
...@@ -99,12 +99,7 @@ TraceStartupConfig::TraceStartupConfig() { ...@@ -99,12 +99,7 @@ TraceStartupConfig::TraceStartupConfig() {
TraceStartupConfig::~TraceStartupConfig() = default; TraceStartupConfig::~TraceStartupConfig() = default;
bool TraceStartupConfig::IsEnabled() const { bool TraceStartupConfig::IsEnabled() const {
// TODO(oysteine): Support early startup tracing using Perfetto return is_enabled_;
// output; right now the early startup tracing gets controlled
// through the TracingController, and the Perfetto output is
// using the Consumer Mojo interface; the two can't be used
// together.
return is_enabled_ && !IsUsingPerfettoOutput();
} }
void TraceStartupConfig::SetDisabled() { void TraceStartupConfig::SetDisabled() {
...@@ -117,15 +112,20 @@ bool TraceStartupConfig::IsTracingStartupForDuration() const { ...@@ -117,15 +112,20 @@ bool TraceStartupConfig::IsTracingStartupForDuration() const {
} }
base::trace_event::TraceConfig TraceStartupConfig::GetTraceConfig() const { base::trace_event::TraceConfig TraceStartupConfig::GetTraceConfig() const {
DCHECK(IsEnabled() || IsUsingPerfettoOutput()); DCHECK(IsEnabled());
return trace_config_; return trace_config_;
} }
int TraceStartupConfig::GetStartupDuration() const { int TraceStartupConfig::GetStartupDuration() const {
DCHECK(IsEnabled() || IsUsingPerfettoOutput()); DCHECK(IsEnabled());
return startup_duration_in_seconds_; return startup_duration_in_seconds_;
} }
TraceStartupConfig::OutputFormat TraceStartupConfig::GetOutputFormat() const {
DCHECK(IsEnabled());
return output_format_;
}
bool TraceStartupConfig::ShouldTraceToResultFile() const { bool TraceStartupConfig::ShouldTraceToResultFile() const {
return IsEnabled() && should_trace_to_result_file_; return IsEnabled() && should_trace_to_result_file_;
} }
...@@ -140,11 +140,6 @@ void TraceStartupConfig::OnTraceToResultFileFinished() { ...@@ -140,11 +140,6 @@ void TraceStartupConfig::OnTraceToResultFileFinished() {
finished_writing_to_file_ = true; finished_writing_to_file_ = true;
} }
bool TraceStartupConfig::IsUsingPerfettoOutput() const {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kPerfettoOutputFile);
}
void TraceStartupConfig::SetBackgroundStartupTracingEnabled(bool enabled) { void TraceStartupConfig::SetBackgroundStartupTracingEnabled(bool enabled) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
base::android::SetBackgroundStartupTracingFlag(enabled); base::android::SetBackgroundStartupTracingFlag(enabled);
...@@ -168,7 +163,6 @@ bool TraceStartupConfig::AttemptAdoptBySessionOwner(SessionOwner owner) { ...@@ -168,7 +163,6 @@ bool TraceStartupConfig::AttemptAdoptBySessionOwner(SessionOwner owner) {
bool TraceStartupConfig::EnableFromCommandLine() { bool TraceStartupConfig::EnableFromCommandLine() {
auto* command_line = base::CommandLine::ForCurrentProcess(); auto* command_line = base::CommandLine::ForCurrentProcess();
// Startup duration can be used by along with perfetto-output-file flag.
if (command_line->HasSwitch(switches::kTraceStartupDuration)) { if (command_line->HasSwitch(switches::kTraceStartupDuration)) {
std::string startup_duration_str = std::string startup_duration_str =
command_line->GetSwitchValueASCII(switches::kTraceStartupDuration); command_line->GetSwitchValueASCII(switches::kTraceStartupDuration);
...@@ -180,6 +174,12 @@ bool TraceStartupConfig::EnableFromCommandLine() { ...@@ -180,6 +174,12 @@ bool TraceStartupConfig::EnableFromCommandLine() {
} }
} }
if (command_line->GetSwitchValueASCII(switches::kTraceStartupFormat) ==
"proto") {
// Default is "json".
output_format_ = OutputFormat::kProto;
}
if (!command_line->HasSwitch(switches::kTraceStartup)) if (!command_line->HasSwitch(switches::kTraceStartup))
return false; return false;
......
...@@ -94,6 +94,11 @@ class TRACING_EXPORT TraceStartupConfig { ...@@ -94,6 +94,11 @@ class TRACING_EXPORT TraceStartupConfig {
kSystemTracing kSystemTracing
}; };
enum class OutputFormat {
kLegacyJSON,
kProto,
};
static TraceStartupConfig* GetInstance(); static TraceStartupConfig* GetInstance();
// Default minimum startup trace config with enough events to debug issues. // Default minimum startup trace config with enough events to debug issues.
...@@ -135,6 +140,8 @@ class TRACING_EXPORT TraceStartupConfig { ...@@ -135,6 +140,8 @@ class TRACING_EXPORT TraceStartupConfig {
SessionOwner GetSessionOwner() const; SessionOwner GetSessionOwner() const;
OutputFormat GetOutputFormat() const;
// Called by a potential session owner to determine if it should take // Called by a potential session owner to determine if it should take
// ownership of the startup tracing session and begin tracing. Returns |true| // ownership of the startup tracing session and begin tracing. Returns |true|
// if the passed |owner| should adopt the session. // if the passed |owner| should adopt the session.
...@@ -152,8 +159,6 @@ class TRACING_EXPORT TraceStartupConfig { ...@@ -152,8 +159,6 @@ class TRACING_EXPORT TraceStartupConfig {
TraceStartupConfig(); TraceStartupConfig();
~TraceStartupConfig(); ~TraceStartupConfig();
bool IsUsingPerfettoOutput() const;
bool EnableFromCommandLine(); bool EnableFromCommandLine();
bool EnableFromConfigFile(); bool EnableFromConfigFile();
bool EnableFromBackgroundTracing(); bool EnableFromBackgroundTracing();
...@@ -170,6 +175,7 @@ class TRACING_EXPORT TraceStartupConfig { ...@@ -170,6 +175,7 @@ class TRACING_EXPORT TraceStartupConfig {
bool finished_writing_to_file_ = false; bool finished_writing_to_file_ = false;
SessionOwner session_owner_ = SessionOwner::kTracingController; SessionOwner session_owner_ = SessionOwner::kTracingController;
bool session_adopted_ = false; bool session_adopted_ = false;
OutputFormat output_format_ = OutputFormat::kLegacyJSON;
DISALLOW_COPY_AND_ASSIGN(TraceStartupConfig); DISALLOW_COPY_AND_ASSIGN(TraceStartupConfig);
}; };
......
...@@ -37,6 +37,14 @@ const char kTraceStartupDuration[] = "trace-startup-duration"; ...@@ -37,6 +37,14 @@ const char kTraceStartupDuration[] = "trace-startup-duration";
// all events since startup. // all events since startup.
const char kTraceStartupFile[] = "trace-startup-file"; const char kTraceStartupFile[] = "trace-startup-file";
// Sets the output format for the trace, valid values are "json" and "proto".
// If not set, the current default is "json".
// "proto", unlike json, supports writing the trace into the output file
// incrementally and is more likely to retain more data if the browser process
// unexpectedly terminates.
// Ignored if "trace-startup-owner" is not "controller".
const char kTraceStartupFormat[] = "trace-startup-format";
// If supplied, sets the tracing record mode and options; otherwise, the default // If supplied, sets the tracing record mode and options; otherwise, the default
// "record-until-full" mode will be used. // "record-until-full" mode will be used.
const char kTraceStartupRecordMode[] = "trace-startup-record-mode"; const char kTraceStartupRecordMode[] = "trace-startup-record-mode";
...@@ -66,13 +74,6 @@ const char kTraceStartupEnablePrivacyFiltering[] = ...@@ -66,13 +74,6 @@ const char kTraceStartupEnablePrivacyFiltering[] =
// Repeat internable data for each TraceEvent in the perfetto proto format. // Repeat internable data for each TraceEvent in the perfetto proto format.
const char kPerfettoDisableInterning[] = "perfetto-disable-interning"; const char kPerfettoDisableInterning[] = "perfetto-disable-interning";
// If supplied, will enable Perfetto startup tracing and stream the
// output to the given file. On Android, if no file is provided, automatically
// generate a file to write the output to.
// TODO(oysteine): Remove once Perfetto starts early enough after
// process startup to be able to replace the legacy startup tracing.
const char kPerfettoOutputFile[] = "perfetto-output-file";
// Sends a pretty-printed version of tracing info to the console. // Sends a pretty-printed version of tracing info to the console.
const char kTraceToConsole[] = "trace-to-console"; const char kTraceToConsole[] = "trace-to-console";
......
...@@ -15,10 +15,10 @@ TRACING_EXPORT extern const char kTraceStartup[]; ...@@ -15,10 +15,10 @@ TRACING_EXPORT extern const char kTraceStartup[];
TRACING_EXPORT extern const char kTraceStartupDuration[]; TRACING_EXPORT extern const char kTraceStartupDuration[];
TRACING_EXPORT extern const char kTraceStartupFile[]; TRACING_EXPORT extern const char kTraceStartupFile[];
TRACING_EXPORT extern const char kTraceStartupRecordMode[]; TRACING_EXPORT extern const char kTraceStartupRecordMode[];
TRACING_EXPORT extern const char kTraceStartupFormat[];
TRACING_EXPORT extern const char kTraceStartupOwner[]; TRACING_EXPORT extern const char kTraceStartupOwner[];
TRACING_EXPORT extern const char kTraceStartupEnablePrivacyFiltering[]; TRACING_EXPORT extern const char kTraceStartupEnablePrivacyFiltering[];
TRACING_EXPORT extern const char kPerfettoDisableInterning[]; TRACING_EXPORT extern const char kPerfettoDisableInterning[];
TRACING_EXPORT extern const char kPerfettoOutputFile[];
TRACING_EXPORT extern const char kTraceToConsole[]; TRACING_EXPORT extern const char kTraceToConsole[];
TRACING_EXPORT extern const char kTraceUploadURL[]; TRACING_EXPORT extern const char kTraceUploadURL[];
......
...@@ -1742,8 +1742,8 @@ source_set("browser") { ...@@ -1742,8 +1742,8 @@ source_set("browser") {
"tracing/file_tracing_provider_impl.h", "tracing/file_tracing_provider_impl.h",
"tracing/memory_instrumentation_util.cc", "tracing/memory_instrumentation_util.cc",
"tracing/memory_instrumentation_util.h", "tracing/memory_instrumentation_util.h",
"tracing/perfetto_file_tracer.cc", "tracing/startup_tracing_controller.cc",
"tracing/perfetto_file_tracer.h", "tracing/startup_tracing_controller.h",
"tracing/tracing_controller_impl.cc", "tracing/tracing_controller_impl.cc",
"tracing/tracing_controller_impl.h", "tracing/tracing_controller_impl.h",
"tracing/tracing_controller_impl_data_endpoint.cc", "tracing/tracing_controller_impl_data_endpoint.cc",
......
...@@ -56,7 +56,6 @@ ...@@ -56,7 +56,6 @@
#include "components/discardable_memory/service/discardable_shared_memory_manager.h" #include "components/discardable_memory/service/discardable_shared_memory_manager.h"
#include "components/services/storage/dom_storage/storage_area_impl.h" #include "components/services/storage/dom_storage/storage_area_impl.h"
#include "components/tracing/common/trace_startup_config.h" #include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/trace_to_console.h"
#include "components/tracing/common/tracing_switches.h" #include "components/tracing/common/tracing_switches.h"
#include "components/viz/host/compositing_mode_reporter_impl.h" #include "components/viz/host/compositing_mode_reporter_impl.h"
#include "components/viz/host/gpu_host_impl.h" #include "components/viz/host/gpu_host_impl.h"
...@@ -90,6 +89,7 @@ ...@@ -90,6 +89,7 @@
#include "content/browser/startup_data_impl.h" #include "content/browser/startup_data_impl.h"
#include "content/browser/startup_task_runner.h" #include "content/browser/startup_task_runner.h"
#include "content/browser/tracing/background_tracing_manager_impl.h" #include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/startup_tracing_controller.h"
#include "content/browser/tracing/tracing_controller_impl.h" #include "content/browser/tracing/tracing_controller_impl.h"
#include "content/browser/utility_process_host.h" #include "content/browser/utility_process_host.h"
#include "content/browser/webrtc/webrtc_internals.h" #include "content/browser/webrtc/webrtc_internals.h"
...@@ -1427,7 +1427,7 @@ void BrowserMainLoop::InitializeMojo() { ...@@ -1427,7 +1427,7 @@ void BrowserMainLoop::InitializeMojo() {
// need to start tracing for all other tracing agents, which require threads. // need to start tracing for all other tracing agents, which require threads.
// We can only do this after starting the main message loop to avoid calling // We can only do this after starting the main message loop to avoid calling
// MessagePumpForUI::ScheduleWork() before MessagePumpForUI::Start(). // MessagePumpForUI::ScheduleWork() before MessagePumpForUI::Start().
TracingControllerImpl::GetInstance()->StartStartupTracingIfNeeded(); StartupTracingController::GetInstance().StartIfNeeded();
#if BUILDFLAG(MOJO_RANDOM_DELAYS_ENABLED) #if BUILDFLAG(MOJO_RANDOM_DELAYS_ENABLED)
mojo::BeginRandomMojoDelays(); mojo::BeginRandomMojoDelays();
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "components/tracing/common/tracing_switches.h" #include "components/tracing/common/tracing_switches.h"
#include "content/browser/browser_main_loop.h" #include "content/browser/browser_main_loop.h"
#include "content/browser/notification_service_impl.h" #include "content/browser/notification_service_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h" #include "content/browser/tracing/startup_tracing_controller.h"
#include "content/common/content_switches_internal.h" #include "content/common/content_switches_internal.h"
#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"
...@@ -167,8 +167,7 @@ void BrowserMainRunnerImpl::Shutdown() { ...@@ -167,8 +167,7 @@ void BrowserMainRunnerImpl::Shutdown() {
main_loop_->PreShutdown(); main_loop_->PreShutdown();
// Finalize the startup tracing session if it is still active. // Finalize the startup tracing session if it is still active.
if (TracingControllerImpl::GetInstance()) StartupTracingController::GetInstance().WaitUntilStopped();
TracingControllerImpl::GetInstance()->FinalizeStartupTracingIfNeeded();
{ {
// The trace event has to stay between profiler creation and destruction. // The trace event has to stay between profiler creation and destruction.
......
...@@ -12,7 +12,7 @@ specific_include_rules = { ...@@ -12,7 +12,7 @@ specific_include_rules = {
"cast_tracing_agent\.": [ "cast_tracing_agent\.": [
"+chromecast/tracing" "+chromecast/tracing"
], ],
"perfetto_file_tracer\.cc": [ "startup_tracing_controller\.cc": [
"+third_party/perfetto" "+third_party/perfetto"
] ]
} }
// Copyright 2019 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 "content/browser/tracing/perfetto_file_tracer.h"
#include <utility>
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h"
#include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/public/browser/tracing_service.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "services/tracing/public/cpp/perfetto/perfetto_config.h"
#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h"
#include "third_party/perfetto/protos/perfetto/config/trace_config.pb.h"
#if defined(OS_ANDROID)
#include "content/browser/android/tracing_controller_android.h"
#endif
namespace content {
namespace {
constexpr base::TimeDelta kReadBufferIntervalInSeconds =
base::TimeDelta::FromSeconds(1);
class BackgroundDrainer : public mojo::DataPipeDrainer::Client {
public:
BackgroundDrainer() {
base::FilePath output_file =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kPerfettoOutputFile);
#if defined(OS_ANDROID)
if (output_file.empty()) {
TracingControllerAndroid::GenerateTracingFilePath(&output_file);
VLOG(0) << "Writing to output file: " << output_file.value();
}
#endif
file_.Initialize(output_file,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
if (!file_.IsValid()) {
LOG(ERROR) << "Failed to open file: " << output_file;
}
}
void StartDrain(mojo::ScopedDataPipeConsumerHandle consumer_handle) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
drainer_.reset(new mojo::DataPipeDrainer(this, std::move(consumer_handle)));
}
private:
// mojo::DataPipeDrainer::Client
void OnDataAvailable(const void* data, size_t num_bytes) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!file_.IsValid()) {
return;
}
size_t written =
file_.WriteAtCurrentPos(static_cast<const char*>(data), num_bytes);
if (written != num_bytes) {
LOG(ERROR) << "Failed writing to trace output file: wrote " << written
<< " out of " << num_bytes << " bytes.";
}
}
// mojo::DataPipeDrainer::Client
void OnDataComplete() override {}
std::unique_ptr<mojo::DataPipeDrainer> drainer_;
base::File file_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(BackgroundDrainer);
};
} // namespace
// static
bool PerfettoFileTracer::ShouldEnable() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kPerfettoOutputFile);
}
// Use USER_VISIBLE priority for the drainer because BEST_EFFORT tasks are not
// run at startup and we want the trace file to be written soon.
PerfettoFileTracer::PerfettoFileTracer()
: background_drainer_(base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN})) {
GetTracingService().BindConsumerHost(
consumer_host_.BindNewPipeAndPassReceiver());
const auto& chrome_config =
tracing::TraceStartupConfig::GetInstance()->GetTraceConfig();
// The output is always proto based. So, enable privacy filtering if argument
// filter is enabled.
bool privacy_filtering = chrome_config.IsArgumentFilterEnabled();
perfetto::TraceConfig trace_config = tracing::GetDefaultPerfettoConfig(
chrome_config, privacy_filtering,
/*convert_to_legacy_json=*/false,
perfetto::protos::gen::ChromeConfig::USER_INITIATED);
int duration_in_seconds =
tracing::TraceStartupConfig::GetInstance()->GetStartupDuration();
trace_config.set_duration_ms(duration_in_seconds * 1000);
// We just need a single global trace buffer, for our data.
trace_config.mutable_buffers()->front().set_size_kb(32 * 1024);
consumer_host_->EnableTracing(
tracing_session_host_.BindNewPipeAndPassReceiver(),
receiver_.BindNewPipeAndPassRemote(), std::move(trace_config));
receiver_.set_disconnect_handler(base::BindOnce(
&PerfettoFileTracer::OnTracingSessionEnded, base::Unretained(this)));
ReadBuffers();
}
PerfettoFileTracer::~PerfettoFileTracer() = default;
void PerfettoFileTracer::OnTracingEnabled() {}
void PerfettoFileTracer::OnTracingDisabled(bool tracing_succeeded) {
DCHECK(tracing_succeeded);
has_been_disabled_ = true;
}
void PerfettoFileTracer::OnNoMorePackets(bool queued_after_disable) {
DCHECK(consumer_host_);
// If this callback happens as the result of a ReadBuffers() call
// which was queued after tracing was disabled, we know there's
// going to be no more packets coming and we can clean up
// the |background_drainer_|.
if (queued_after_disable) {
consumer_host_.reset();
background_drainer_.Reset();
return;
}
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&PerfettoFileTracer::ReadBuffers,
weak_factory_.GetWeakPtr()),
kReadBufferIntervalInSeconds);
}
void PerfettoFileTracer::ReadBuffers() {
DCHECK(consumer_host_);
mojo::DataPipe data_pipe;
tracing_session_host_->ReadBuffers(
std::move(data_pipe.producer_handle),
base::BindOnce(
[](PerfettoFileTracer* file_tracing, bool queued_after_disable) {
file_tracing->OnNoMorePackets(queued_after_disable);
},
base::Unretained(this), has_been_disabled_));
background_drainer_.AsyncCall(&BackgroundDrainer::StartDrain)
.WithArgs(std::move(data_pipe.consumer_handle));
}
void PerfettoFileTracer::OnTracingSessionEnded() {
receiver_.reset();
tracing_session_host_.reset();
}
} // namespace content
// Copyright 2019 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.
#ifndef CONTENT_BROWSER_TRACING_PERFETTO_FILE_TRACER_H_
#define CONTENT_BROWSER_TRACING_PERFETTO_FILE_TRACER_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/task/task_traits.h"
#include "base/threading/sequence_bound.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/tracing/public/mojom/perfetto_service.mojom.h"
namespace content {
namespace {
class BackgroundDrainer;
} // namespace
// This is currently only used for tracing startup using Perfetto
// as the backend, rather than TraceLog. It will directly stream
// protos to a file specified with the '--perfetto-output-file'
// switch.
class PerfettoFileTracer : public tracing::mojom::TracingSessionClient {
public:
PerfettoFileTracer();
~PerfettoFileTracer() override;
static bool ShouldEnable();
// tracing::mojom::TracingSessionClient implementation:
void OnTracingEnabled() override;
void OnTracingDisabled(bool tracing_succeeded) override;
bool is_finished_for_testing() const { return !background_drainer_; }
private:
void OnNoMorePackets(bool queued_after_disable);
void ReadBuffers();
void OnTracingSessionEnded();
base::SequenceBound<BackgroundDrainer> background_drainer_;
mojo::Receiver<tracing::mojom::TracingSessionClient> receiver_{this};
mojo::Remote<tracing::mojom::TracingSessionHost> tracing_session_host_;
mojo::Remote<tracing::mojom::ConsumerHost> consumer_host_;
bool has_been_disabled_ = false;
base::WeakPtrFactory<PerfettoFileTracer> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(PerfettoFileTracer);
};
} // namespace content
#endif // CONTENT_BROWSER_TRACING_PERFETTO_FILE_TRACER_H_
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h" #include "base/test/test_timeouts.h"
...@@ -11,7 +12,6 @@ ...@@ -11,7 +12,6 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "components/tracing/common/trace_startup_config.h" #include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/tracing_switches.h" #include "components/tracing/common/tracing_switches.h"
#include "content/browser/tracing/perfetto_file_tracer.h"
#include "content/browser/tracing/tracing_controller_impl.h" #include "content/browser/tracing/tracing_controller_impl.h"
#include "content/public/test/browser_test.h" #include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
...@@ -72,12 +72,6 @@ class CommandlineStartupTracingTest : public ContentBrowserTest { ...@@ -72,12 +72,6 @@ class CommandlineStartupTracingTest : public ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(CommandlineStartupTracingTest, IN_PROC_BROWSER_TEST_F(CommandlineStartupTracingTest,
MAYBE_TestStartupTracing) { MAYBE_TestStartupTracing) {
EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html"))); EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html")));
WaitForCondition(base::BindRepeating([]() {
return !TracingController::GetInstance()->IsTracing();
}),
"trace end");
EXPECT_FALSE(tracing::TraceStartupConfig::GetInstance()->IsEnabled());
EXPECT_FALSE(TracingController::GetInstance()->IsTracing());
WaitForCondition(base::BindRepeating([]() { WaitForCondition(base::BindRepeating([]() {
return tracing::TraceStartupConfig::GetInstance() return tracing::TraceStartupConfig::GetInstance()
->finished_writing_to_file_for_testing(); ->finished_writing_to_file_for_testing();
...@@ -87,8 +81,8 @@ IN_PROC_BROWSER_TEST_F(CommandlineStartupTracingTest, ...@@ -87,8 +81,8 @@ IN_PROC_BROWSER_TEST_F(CommandlineStartupTracingTest,
std::string trace; std::string trace;
base::ScopedAllowBlockingForTesting allow_blocking; base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(base::ReadFileToString(temp_file_path_, &trace)); ASSERT_TRUE(base::ReadFileToString(temp_file_path_, &trace));
EXPECT_TRUE( EXPECT_TRUE(base::JSONReader::Read(trace));
trace.find("TracingControllerImpl::InitStartupTracingForDuration") != EXPECT_TRUE(trace.find("StartupTracingController::Start") !=
std::string::npos); std::string::npos);
} }
...@@ -160,55 +154,4 @@ IN_PROC_BROWSER_TEST_F(StartupTracingInProcessTest, TestFilledStartupBuffer) { ...@@ -160,55 +154,4 @@ IN_PROC_BROWSER_TEST_F(StartupTracingInProcessTest, TestFilledStartupBuffer) {
wait_for_stop.Run(); wait_for_stop.Run();
} }
class BackgroundStartupTracingTest : public ContentBrowserTest {
public:
BackgroundStartupTracingTest() = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
base::CreateTemporaryFile(&temp_file_path_);
auto* startup_config = tracing::TraceStartupConfig::GetInstance();
startup_config->enable_background_tracing_for_testing_ = true;
startup_config->EnableFromBackgroundTracing();
startup_config->startup_duration_in_seconds_ = 3;
command_line->AppendSwitchASCII(switches::kPerfettoOutputFile,
temp_file_path_.AsUTF8Unsafe());
}
protected:
base::FilePath temp_file_path_;
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundStartupTracingTest);
};
#if !defined(OS_ANDROID)
#define MAYBE_TestStartupTracing DISABLED_TestStartupTracing
#else
#define MAYBE_TestStartupTracing TestStartupTracing
#endif
IN_PROC_BROWSER_TEST_F(BackgroundStartupTracingTest, MAYBE_TestStartupTracing) {
EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html")));
EXPECT_FALSE(tracing::TraceStartupConfig::GetInstance()->IsEnabled());
EXPECT_FALSE(TracingController::GetInstance()->IsTracing());
WaitForCondition(base::BindRepeating([]() {
return TracingControllerImpl::GetInstance()
->perfetto_file_tracer_for_testing()
->is_finished_for_testing();
}),
"finish file write");
std::string trace;
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(base::ReadFileToString(temp_file_path_, &trace));
tracing::PrivacyFilteringCheck checker;
checker.CheckProtoForUnexpectedFields(trace);
EXPECT_GT(checker.stats().track_event, 0u);
EXPECT_GT(checker.stats().process_desc, 0u);
EXPECT_GT(checker.stats().thread_desc, 0u);
EXPECT_TRUE(checker.stats().has_interned_names);
EXPECT_TRUE(checker.stats().has_interned_categories);
EXPECT_TRUE(checker.stats().has_interned_source_locations);
}
} // namespace content } // namespace content
// 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 "content/browser/tracing/startup_tracing_controller.h"
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/run_loop.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/trace_event/typed_macros.h"
#include "build/build_config.h"
#include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/tracing/public/cpp/perfetto/perfetto_config.h"
#include "services/tracing/public/cpp/perfetto/trace_packet_tokenizer.h"
#include "third_party/perfetto/include/perfetto/ext/tracing/core/trace_packet.h"
#include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h"
#include "third_party/perfetto/include/perfetto/tracing/tracing.h"
#if defined(OS_ANDROID)
#include "content/browser/android/tracing_controller_android.h"
#endif // defined(OS_ANDROID)
namespace content {
class StartupTracingController::BackgroundTracer {
public:
BackgroundTracer(base::FilePath output_file,
tracing::TraceStartupConfig::OutputFormat output_format,
perfetto::TraceConfig trace_config,
base::OnceClosure on_tracing_finished)
: state_(State::kTracing),
task_runner_(base::SequencedTaskRunnerHandle::Get()),
output_file_(output_file),
output_format_(output_format),
on_tracing_finished_(std::move(on_tracing_finished)) {
tracing_session_ = perfetto::Tracing::NewTrace();
tracing_session_->Setup(trace_config);
tracing_session_->StartBlocking();
tracing_session_->SetOnStopCallback([&]() { OnTracingStopped(); });
TRACE_EVENT("startup", "StartupTracingController::Start");
}
void Stop() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (state_ != State::kTracing)
return;
tracing_session_->StopBlocking();
}
void OnTracingStopped() {
if (!task_runner_->RunsTasksInCurrentSequence()) {
// The owner of BackgroundTracer is responsible for ensuring that
// BackgroundTracer stays alive until |on_tracing_finished_| is called.
task_runner_->PostTask(FROM_HERE,
base::BindOnce(&BackgroundTracer::OnTracingStopped,
base::Unretained(this)));
return;
}
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(state_, State::kTracing);
state_ = State::kWritingToFile;
if (output_format_ ==
tracing::TraceStartupConfig::OutputFormat::kLegacyJSON) {
trace_packet_tokenizer_ =
std::make_unique<tracing::TracePacketTokenizer>();
}
file_ = base::CreateAndOpenTemporaryFileInDir(output_file_.DirName(),
&written_to_file_);
if (!file_.IsValid()) {
file_.Initialize(output_file_,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
written_to_file_ = output_file_;
}
// The owner of BackgroundTracer is responsible for ensuring that
// BackgroundTracer stays alive until |on_tracing_finished_| is called.
tracing_session_->ReadTrace(
[this](perfetto::TracingSession::ReadTraceCallbackArgs args) {
WriteData(args.data, args.size);
if (args.has_more)
return;
file_.Close();
if (written_to_file_ != output_file_) {
base::File::Error error;
if (!base::ReplaceFile(written_to_file_, output_file_, &error)) {
LOG(ERROR) << "Cannot move file '" << written_to_file_ << "' to '"
<< output_file_
<< "' : " << base::File::ErrorToString(error);
}
}
std::move(on_tracing_finished_).Run();
state_ = State::kFinished;
});
}
private:
void WriteData(const char* data, size_t size) {
// Last chunk can be empty.
if (size == 0)
return;
// Proto files should be written directly to the file.
if (output_format_ == tracing::TraceStartupConfig::OutputFormat::kProto) {
file_.WriteAtCurrentPos(data, size);
return;
}
// For JSON, we need to extract raw data from the packet.
DCHECK(trace_packet_tokenizer_);
std::vector<perfetto::TracePacket> packets = trace_packet_tokenizer_->Parse(
reinterpret_cast<const uint8_t*>(data), size);
for (const auto& packet : packets) {
for (const auto& slice : packet.slices()) {
file_.WriteAtCurrentPos(reinterpret_cast<const char*>(slice.start),
slice.size);
}
}
}
enum class State {
kTracing,
kWritingToFile,
kFinished,
};
State state_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
base::FilePath output_file_;
base::FilePath written_to_file_;
base::File file_;
const tracing::TraceStartupConfig::OutputFormat output_format_;
// Tokenizer to extract the json data from the data received from the tracing
// service.
std::unique_ptr<tracing::TracePacketTokenizer> trace_packet_tokenizer_;
base::OnceClosure on_tracing_finished_;
std::unique_ptr<perfetto::TracingSession> tracing_session_;
SEQUENCE_CHECKER(sequence_checker_);
};
namespace {
base::FilePath GetStartupTraceFileName() {
base::FilePath trace_file;
trace_file = tracing::TraceStartupConfig::GetInstance()->GetResultFile();
if (trace_file.empty()) {
#if defined(OS_ANDROID)
TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
#else
// Default to saving the startup trace into the current dir.
trace_file = base::FilePath().AppendASCII("chrometrace.log");
#endif
}
return trace_file;
}
} // namespace
StartupTracingController::StartupTracingController() = default;
StartupTracingController::~StartupTracingController() = default;
// static
StartupTracingController& StartupTracingController::GetInstance() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
static base::NoDestructor<StartupTracingController> g_instance;
return *g_instance;
}
void StartupTracingController::StartIfNeeded() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(state_, State::kRunning);
auto* trace_startup_config = tracing::TraceStartupConfig::GetInstance();
if (!trace_startup_config->AttemptAdoptBySessionOwner(
tracing::TraceStartupConfig::SessionOwner::kTracingController)) {
return;
}
state_ = State::kRunning;
// Use USER_VISIBLE priority for the drainer because BEST_EFFORT tasks are not
// run at startup and we want the trace file to be written soon.
auto background_task_runner = base::ThreadPool::CreateSequencedTaskRunner(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
auto output_format =
tracing::TraceStartupConfig::GetInstance()->GetOutputFormat();
const auto& chrome_config =
tracing::TraceStartupConfig::GetInstance()->GetTraceConfig();
perfetto::TraceConfig perfetto_config = tracing::GetDefaultPerfettoConfig(
chrome_config, /*privacy_filtering_enabled=*/false,
/*convert_to_legacy_json=*/output_format ==
tracing::TraceStartupConfig::OutputFormat::kLegacyJSON);
int duration_in_seconds =
tracing::TraceStartupConfig::GetInstance()->GetStartupDuration();
perfetto_config.set_duration_ms(duration_in_seconds * 1000);
if (output_file_.empty())
output_file_ = GetStartupTraceFileName();
background_tracer_ = base::SequenceBound<BackgroundTracer>(
std::move(background_task_runner), output_file_, output_format,
perfetto_config,
base::BindOnce(
[](StartupTracingController* controller) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&StartupTracingController::OnStoppedOnUIThread,
base::Unretained(controller)));
},
this));
}
void StartupTracingController::Stop(base::OnceClosure on_tracing_finished) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (state_ == State::kNotRunning) {
std::move(on_tracing_finished).Run();
return;
}
DCHECK(!on_tracing_finished_) << "Stop() should be called only once.";
on_tracing_finished_ = std::move(on_tracing_finished);
background_tracer_.AsyncCall(&BackgroundTracer::Stop);
}
void StartupTracingController::OnStoppedOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_EQ(state_, State::kRunning);
state_ = State::kNotRunning;
background_tracer_.Reset();
if (on_tracing_finished_)
std::move(on_tracing_finished_).Run();
VLOG(0) << "Completed startup tracing to " << output_file_;
tracing::TraceStartupConfig::GetInstance()->OnTraceToResultFileFinished();
tracing::TraceStartupConfig::GetInstance()->SetDisabled();
}
void StartupTracingController::WaitUntilStopped() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::RunLoop run_loop;
Stop(run_loop.QuitClosure());
run_loop.Run();
}
} // namespace content
// 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.
#ifndef CONTENT_BROWSER_TRACING_STARTUP_TRACING_CONTROLLER_H_
#define CONTENT_BROWSER_TRACING_STARTUP_TRACING_CONTROLLER_H_
#include "base/threading/sequence_bound.h"
namespace content {
// Class responsible for starting and stopping startup tracing as configured by
// StartupTracingConfig. All interactions with it are limited to UI thread, but
// the actual logic lives on a background ThreadPool sequence.
class StartupTracingController {
public:
StartupTracingController();
~StartupTracingController();
static StartupTracingController& GetInstance();
void StartIfNeeded();
void WaitUntilStopped();
private:
void Stop(base::OnceClosure on_finished_callback);
void OnStoppedOnUIThread();
enum class State {
kRunning,
kNotRunning,
};
State state_ = State::kNotRunning;
// All actual interactions with the tracing service and the process of writing
// files happens on a background thread.
class BackgroundTracer;
base::SequenceBound<BackgroundTracer> background_tracer_;
base::OnceClosure on_tracing_finished_;
base::FilePath output_file_;
};
} // namespace content
#endif // CONTENT_BROWSER_TRACING_STARTUP_TRACING_CONTROLLER_H_
...@@ -26,12 +26,10 @@ ...@@ -26,12 +26,10 @@
#include "base/values.h" #include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "build/chromeos_buildflags.h" #include "build/chromeos_buildflags.h"
#include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/trace_to_console.h" #include "components/tracing/common/trace_to_console.h"
#include "components/tracing/common/tracing_switches.h" #include "components/tracing/common/tracing_switches.h"
#include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/tracing/file_tracing_provider_impl.h" #include "content/browser/tracing/file_tracing_provider_impl.h"
#include "content/browser/tracing/perfetto_file_tracer.h"
#include "content/browser/tracing/tracing_ui.h" #include "content/browser/tracing/tracing_ui.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
...@@ -164,11 +162,6 @@ std::string GetClockOffsetSinceEpoch() { ...@@ -164,11 +162,6 @@ std::string GetClockOffsetSinceEpoch() {
} }
#endif #endif
void OnStoppedStartupTracing(const base::FilePath& trace_file) {
VLOG(0) << "Completed startup tracing to " << trace_file.value();
tracing::TraceStartupConfig::GetInstance()->OnTraceToResultFileFinished();
}
} // namespace } // namespace
TracingController* TracingController::GetInstance() { TracingController* TracingController::GetInstance() {
...@@ -184,13 +177,6 @@ TracingControllerImpl::TracingControllerImpl() ...@@ -184,13 +177,6 @@ TracingControllerImpl::TracingControllerImpl()
AddAgents(); AddAgents();
g_tracing_controller = this; g_tracing_controller = this;
// TODO(oysteine): Startup tracing using Perfetto
// is enabled by the Mojo consumer in content/browser
// for now; this is too late in the browser startup
// process however.
if (PerfettoFileTracer::ShouldEnable())
perfetto_file_tracer_ = std::make_unique<PerfettoFileTracer>();
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
// Bind hwclass once the statistics are available. // Bind hwclass once the statistics are available.
chromeos::system::StatisticsProvider::GetInstance() chromeos::system::StatisticsProvider::GetInstance()
...@@ -449,106 +435,6 @@ bool TracingControllerImpl::StartTracing( ...@@ -449,106 +435,6 @@ bool TracingControllerImpl::StartTracing(
return true; return true;
} }
void TracingControllerImpl::StartStartupTracingIfNeeded() {
auto* trace_startup_config = tracing::TraceStartupConfig::GetInstance();
if (trace_startup_config->AttemptAdoptBySessionOwner(
tracing::TraceStartupConfig::SessionOwner::kTracingController)) {
StartTracing(trace_startup_config->GetTraceConfig(),
StartTracingDoneCallback());
} else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kTraceToConsole)) {
StartTracing(tracing::GetConfigForTraceToConsole(),
StartTracingDoneCallback());
}
if (trace_startup_config->IsTracingStartupForDuration()) {
TRACE_EVENT0("startup",
"TracingControllerImpl::InitStartupTracingForDuration");
InitStartupTracingForDuration();
}
}
base::FilePath TracingControllerImpl::GetStartupTraceFileName() const {
base::FilePath trace_file;
trace_file = tracing::TraceStartupConfig::GetInstance()->GetResultFile();
if (trace_file.empty()) {
#if defined(OS_ANDROID)
TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
#else
// Default to saving the startup trace into the current dir.
trace_file = base::FilePath().AppendASCII("chrometrace.log");
#endif
}
return trace_file;
}
void TracingControllerImpl::InitStartupTracingForDuration() {
DCHECK(tracing::TraceStartupConfig::GetInstance()
->IsTracingStartupForDuration());
startup_trace_file_ = GetStartupTraceFileName();
startup_trace_timer_.Start(
FROM_HERE,
base::TimeDelta::FromSeconds(
tracing::TraceStartupConfig::GetInstance()->GetStartupDuration()),
this, &TracingControllerImpl::EndStartupTracing);
}
void TracingControllerImpl::EndStartupTracing() {
// Do nothing if startup tracing is already stopped.
if (!tracing::TraceStartupConfig::GetInstance()->IsEnabled())
return;
// Use USER_VISIBLE priority because BEST_EFFORT tasks are not run at startup
// and we want the trace file to be written soon.
StopTracing(CreateFileEndpoint(
startup_trace_file_,
base::BindOnce(OnStoppedStartupTracing, startup_trace_file_),
base::TaskPriority::USER_VISIBLE));
}
void TracingControllerImpl::FinalizeStartupTracingIfNeeded() {
// There are two cases:
// 1. Startup duration is not reached.
// 2. Or if the trace should be saved to file for --trace-config-file flag.
base::Optional<base::FilePath> startup_trace_file;
if (startup_trace_timer_.IsRunning()) {
startup_trace_timer_.Stop();
if (startup_trace_file_ != base::FilePath().AppendASCII("none")) {
startup_trace_file = startup_trace_file_;
}
} else if (tracing::TraceStartupConfig::GetInstance()
->ShouldTraceToResultFile()) {
startup_trace_file = GetStartupTraceFileName();
}
if (!startup_trace_file)
return;
// Perfetto currently doesn't support tracing during shutdown as the trace
// buffer is lost when the service is shut down, so we wait until the trace is
// complete. See also crbug.com/944107.
// TODO(eseckler): Avoid the nestedRunLoop here somehow.
base::RunLoop run_loop;
// We may not have completed startup yet when we attempt to write the trace,
// and thus tasks with BEST_EFFORT may not be run. Choose a non-background
// priority to avoid blocking forever.
const base::TaskPriority kWritePriority = base::TaskPriority::USER_VISIBLE;
bool success = StopTracing(CreateFileEndpoint(
startup_trace_file.value(),
base::BindOnce(
[](base::FilePath trace_file, base::OnceClosure quit_closure) {
OnStoppedStartupTracing(trace_file);
std::move(quit_closure).Run();
},
startup_trace_file.value(), run_loop.QuitClosure()),
kWritePriority));
if (!success)
return;
run_loop.Run();
}
bool TracingControllerImpl::StopTracing( bool TracingControllerImpl::StopTracing(
const scoped_refptr<TraceDataEndpoint>& trace_data_endpoint) { const scoped_refptr<TraceDataEndpoint>& trace_data_endpoint) {
return StopTracing(std::move(trace_data_endpoint), ""); return StopTracing(std::move(trace_data_endpoint), "");
...@@ -575,7 +461,6 @@ bool TracingControllerImpl::StopTracing( ...@@ -575,7 +461,6 @@ bool TracingControllerImpl::StopTracing(
// removed. // removed.
CHECK(privacy_filtering_enabled || !trace_config_->IsArgumentFilterEnabled()); CHECK(privacy_filtering_enabled || !trace_config_->IsArgumentFilterEnabled());
tracing::TraceStartupConfig::GetInstance()->SetDisabled();
trace_data_endpoint_ = std::move(trace_data_endpoint); trace_data_endpoint_ = std::move(trace_data_endpoint);
is_data_complete_ = false; is_data_complete_ = false;
read_buffers_complete_ = false; read_buffers_complete_ = false;
......
...@@ -45,7 +45,6 @@ class BaseAgent; ...@@ -45,7 +45,6 @@ class BaseAgent;
namespace content { namespace content {
class PerfettoFileTracer;
class TracingDelegate; class TracingDelegate;
class TracingControllerImpl : public TracingController, class TracingControllerImpl : public TracingController,
...@@ -86,22 +85,6 @@ class TracingControllerImpl : public TracingController, ...@@ -86,22 +85,6 @@ class TracingControllerImpl : public TracingController,
CONTENT_EXPORT void SetTracingDelegateForTesting( CONTENT_EXPORT void SetTracingDelegateForTesting(
std::unique_ptr<TracingDelegate> delegate); std::unique_ptr<TracingDelegate> delegate);
// If command line flags specify startup tracing options, adopts the startup
// tracing session and relays it to all tracing agents. Note that the local
// TraceLog has already been enabled at this point by
// tracing::EnableStartupTracingIfNeeded(), before threads were available.
// Requires browser threads to have started and a started main message loop.
void StartStartupTracingIfNeeded();
// Should be called before browser main loop shutdown. If startup tracing is
// tracing to a file and is still active, this stops the duration timer if it
// exists.
void FinalizeStartupTracingIfNeeded();
PerfettoFileTracer* perfetto_file_tracer_for_testing() const {
return perfetto_file_tracer_.get();
}
private: private:
friend std::default_delete<TracingControllerImpl>; friend std::default_delete<TracingControllerImpl>;
...@@ -125,9 +108,7 @@ class TracingControllerImpl : public TracingController, ...@@ -125,9 +108,7 @@ class TracingControllerImpl : public TracingController,
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
void OnMachineStatisticsLoaded(); void OnMachineStatisticsLoaded();
#endif #endif
base::FilePath GetStartupTraceFileName() const;
std::unique_ptr<PerfettoFileTracer> perfetto_file_tracer_;
mojo::Remote<tracing::mojom::ConsumerHost> consumer_host_; mojo::Remote<tracing::mojom::ConsumerHost> consumer_host_;
mojo::Remote<tracing::mojom::TracingSessionHost> tracing_session_host_; mojo::Remote<tracing::mojom::TracingSessionHost> tracing_session_host_;
mojo::Receiver<tracing::mojom::TracingSessionClient> receiver_{this}; mojo::Receiver<tracing::mojom::TracingSessionClient> receiver_{this};
...@@ -141,10 +122,6 @@ class TracingControllerImpl : public TracingController, ...@@ -141,10 +122,6 @@ class TracingControllerImpl : public TracingController,
bool is_data_complete_ = false; bool is_data_complete_ = false;
bool read_buffers_complete_ = false; bool read_buffers_complete_ = false;
base::FilePath startup_trace_file_;
// This timer initiates trace file saving.
base::OneShotTimer startup_trace_timer_;
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
bool are_statistics_loaded_ = false; bool are_statistics_loaded_ = false;
std::string hardware_class_; std::string hardware_class_;
......
...@@ -44,11 +44,6 @@ void EnableStartupTracingIfNeeded() { ...@@ -44,11 +44,6 @@ void EnableStartupTracingIfNeeded() {
// unique uuid for generating track ids. // unique uuid for generating track ids.
PerfettoTracedProcess::Get()->SetupClientLibrary(); PerfettoTracedProcess::Get()->SetupClientLibrary();
// TODO(oysteine): Support startup tracing to a perfetto protobuf trace. This
// should also enable TraceLog and call SetupStartupTracing().
if (command_line.HasSwitch(switches::kPerfettoOutputFile))
return;
// Ensure TraceLog is initialized first. // Ensure TraceLog is initialized first.
// https://crbug.com/764357 // https://crbug.com/764357
TraceLog::GetInstance(); TraceLog::GetInstance();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment