| Index: content/browser/tracing/tracing_controller_impl.cc
|
| diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
|
| index bc2eb6ea2f6d08911a05027ac525673e46d70562..33c236117761a07bf20ec6ba9d4a89e291926cd4 100644
|
| --- a/content/browser/tracing/tracing_controller_impl.cc
|
| +++ b/content/browser/tracing/tracing_controller_impl.cc
|
| @@ -45,6 +45,9 @@ namespace {
|
| base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
|
| LAZY_INSTANCE_INITIALIZER;
|
|
|
| +const char kChromeTracingAgentName[] = "chrome";
|
| +const char kETWTracingAgentName[] = "etw";
|
| +const char kChromeTraceLabel[] = "traceEvents";
|
|
|
| std::string GetNetworkTypeString() {
|
| switch (net::NetworkChangeNotifier::GetConnectionType()) {
|
| @@ -145,14 +148,8 @@ TracingControllerImpl::TracingControllerImpl()
|
| approximate_event_count_(0),
|
| pending_memory_dump_ack_count_(0),
|
| failed_memory_dump_count_(0),
|
| - // Tracing may have been enabled by ContentMainRunner if kTraceStartup
|
| - // is specified in command line.
|
| -#if defined(OS_CHROMEOS) || defined(OS_WIN)
|
| - is_system_tracing_(false),
|
| -#endif
|
| is_tracing_(false),
|
| - is_monitoring_(false),
|
| - is_power_tracing_(false) {
|
| + is_monitoring_(false) {
|
| base::trace_event::MemoryDumpManager::GetInstance()->Initialize(
|
| this /* delegate */, true /* is_coordinator */);
|
|
|
| @@ -210,10 +207,12 @@ bool TracingControllerImpl::StartTracing(
|
| const TraceConfig& trace_config,
|
| const StartTracingDoneCallback& callback) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + DCHECK(additional_tracing_agents_.empty());
|
|
|
| if (!can_start_tracing())
|
| return false;
|
| is_tracing_ = true;
|
| + start_tracing_done_callback_ = callback;
|
|
|
| #if defined(OS_ANDROID)
|
| if (pending_get_categories_done_callback_.is_null())
|
| @@ -221,46 +220,33 @@ bool TracingControllerImpl::StartTracing(
|
| #endif
|
|
|
| if (trace_config.IsSystraceEnabled()) {
|
| - DCHECK(!is_power_tracing_);
|
| - is_power_tracing_ = PowerTracingAgent::GetInstance()->StartTracing();
|
| + if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config))
|
| + additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance());
|
| #if defined(OS_CHROMEOS)
|
| - DCHECK(!is_system_tracing_);
|
| - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
|
| - StartSystemTracing();
|
| - is_system_tracing_ = true;
|
| + chromeos::DebugDaemonClient* debug_daemon =
|
| + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
|
| + if (debug_daemon && debug_daemon->StartAgentTracing(trace_config)) {
|
| + debug_daemon->SetStopAgentTracingTaskRunner(
|
| + BrowserThread::GetBlockingPool());
|
| + additional_tracing_agents_.push_back(
|
| + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient());
|
| + }
|
| #elif defined(OS_WIN)
|
| - DCHECK(!is_system_tracing_);
|
| - is_system_tracing_ =
|
| - EtwSystemEventConsumer::GetInstance()->StartSystemTracing();
|
| + if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing(
|
| + trace_config)) {
|
| + additional_tracing_agents_.push_back(
|
| + EtwSystemEventConsumer::GetInstance());
|
| + }
|
| #endif
|
| }
|
|
|
| // TraceLog may have been enabled in startup tracing before threads are ready.
|
| if (TraceLog::GetInstance()->IsEnabled())
|
| return true;
|
| -
|
| - base::Closure on_start_tracing_done_callback =
|
| - base::Bind(&TracingControllerImpl::OnStartTracingDone,
|
| - base::Unretained(this),
|
| - trace_config, callback);
|
| - if (!BrowserThread::PostTask(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
|
| - base::Unretained(this), trace_config,
|
| - base::trace_event::TraceLog::RECORDING_MODE,
|
| - on_start_tracing_done_callback))) {
|
| - // BrowserThread::PostTask fails if the threads haven't been created yet,
|
| - // so it should be safe to just use TraceLog::SetEnabled directly.
|
| - base::trace_event::TraceLog::GetInstance()->SetEnabled(
|
| - trace_config, base::trace_event::TraceLog::RECORDING_MODE);
|
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| - on_start_tracing_done_callback);
|
| - }
|
| -
|
| - return true;
|
| + return StartAgentTracing(trace_config);
|
| }
|
|
|
| -void TracingControllerImpl::OnStartTracingDone(
|
| +void TracingControllerImpl::OnStartAgentTracingDone(
|
| const TraceConfig& trace_config,
|
| const StartTracingDoneCallback& callback) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| @@ -325,63 +311,15 @@ void TracingControllerImpl::OnStopTracingDone() {
|
| pending_stop_tracing_ack_count_ = trace_message_filters_.size() + 1;
|
| pending_stop_tracing_filters_ = trace_message_filters_;
|
|
|
| -#if defined(OS_CHROMEOS) || defined(OS_WIN)
|
| - if (is_system_tracing_) {
|
| - // Disable system tracing.
|
| - is_system_tracing_ = false;
|
| - ++pending_stop_tracing_ack_count_;
|
| -
|
| -#if defined(OS_CHROMEOS)
|
| - scoped_refptr<base::TaskRunner> task_runner =
|
| - BrowserThread::GetBlockingPool();
|
| - chromeos::DBusThreadManager::Get()
|
| - ->GetDebugDaemonClient()
|
| - ->RequestStopSystemTracing(
|
| - task_runner,
|
| - base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
|
| - base::Unretained(this)));
|
| -#elif defined(OS_WIN)
|
| - EtwSystemEventConsumer::GetInstance()->StopSystemTracing(
|
| - base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
|
| + pending_stop_tracing_ack_count_ += additional_tracing_agents_.size();
|
| + for (auto it : additional_tracing_agents_) {
|
| + it->StopAgentTracing(
|
| + base::Bind(&TracingControllerImpl::OnEndAgentTracingAcked,
|
| base::Unretained(this)));
|
| -#endif
|
| - }
|
| -#endif // defined(OS_CHROMEOS) || defined(OS_WIN)
|
| -
|
| - if (is_power_tracing_) {
|
| - is_power_tracing_ = false;
|
| - ++pending_stop_tracing_ack_count_;
|
| - PowerTracingAgent::GetInstance()->StopTracing(
|
| - base::Bind(&TracingControllerImpl::OnEndPowerTracingAcked,
|
| - base::Unretained(this)));
|
| - }
|
| -
|
| - // Handle special case of zero child processes by immediately flushing the
|
| - // trace log. Once the flush has completed the caller will be notified that
|
| - // tracing has ended.
|
| - if (pending_stop_tracing_ack_count_ == 1) {
|
| - // Flush/cancel asynchronously now, because we don't have any children to
|
| - // wait for.
|
| - if (trace_data_sink_) {
|
| - TraceLog::GetInstance()->Flush(
|
| - base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
|
| - base::Unretained(this)),
|
| - true);
|
| - } else {
|
| - TraceLog::GetInstance()->CancelTracing(
|
| - base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
|
| - base::Unretained(this)));
|
| - }
|
| }
|
| + additional_tracing_agents_.clear();
|
|
|
| - // Notify all child processes.
|
| - for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
|
| - it != trace_message_filters_.end(); ++it) {
|
| - if (trace_data_sink_)
|
| - it->get()->SendEndTracing();
|
| - else
|
| - it->get()->SendCancelTracing();
|
| - }
|
| + StopAgentTracing(StopAgentTracingCallback());
|
| }
|
|
|
| bool TracingControllerImpl::StartMonitoring(
|
| @@ -738,39 +676,26 @@ void TracingControllerImpl::OnStopTracingAcked(
|
| }
|
| }
|
|
|
| -void TracingControllerImpl::OnEndPowerTracingAcked(
|
| - const scoped_refptr<base::RefCountedString>& events_str_ptr) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| -
|
| - if (trace_data_sink_.get()) {
|
| - std::string json_string = base::GetQuotedJSONString(events_str_ptr->data());
|
| - trace_data_sink_->SetPowerTrace(json_string);
|
| - }
|
| - std::vector<std::string> category_groups;
|
| - OnStopTracingAcked(NULL, category_groups);
|
| -}
|
| -
|
| -#if defined(OS_CHROMEOS) || defined(OS_WIN)
|
| -void TracingControllerImpl::OnEndSystemTracingAcked(
|
| +void TracingControllerImpl::OnEndAgentTracingAcked(
|
| + const std::string& agent_name,
|
| + const std::string& events_label,
|
| const scoped_refptr<base::RefCountedString>& events_str_ptr) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
|
| if (trace_data_sink_.get()) {
|
| -#if defined(OS_WIN)
|
| - // The Windows kernel events are kept into a JSon format stored as string
|
| - // and must not be escaped.
|
| - std::string json_string = events_str_ptr->data();
|
| -#else
|
| - std::string json_string =
|
| - base::GetQuotedJSONString(events_str_ptr->data());
|
| -#endif
|
| - trace_data_sink_->SetSystemTrace(json_string);
|
| + std::string json_string;
|
| + if (agent_name == kETWTracingAgentName) {
|
| + // The Windows kernel events are kept into a JSON format stored as string
|
| + // and must not be escaped.
|
| + json_string = events_str_ptr->data();
|
| + } else {
|
| + json_string = base::GetQuotedJSONString(events_str_ptr->data());
|
| + }
|
| + trace_data_sink_->AddAgentTrace(events_label, json_string);
|
| }
|
| - DCHECK(!is_system_tracing_);
|
| std::vector<std::string> category_groups;
|
| OnStopTracingAcked(NULL, category_groups);
|
| }
|
| -#endif
|
|
|
| void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked(
|
| TraceMessageFilter* trace_message_filter) {
|
| @@ -924,6 +849,85 @@ void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
|
| tracing_uis_.erase(it);
|
| }
|
|
|
| +std::string TracingControllerImpl::GetTracingAgentName() {
|
| + return kChromeTracingAgentName;
|
| +}
|
| +
|
| +std::string TracingControllerImpl::GetTraceEventLabel() {
|
| + return kChromeTraceLabel;
|
| +}
|
| +
|
| +bool TracingControllerImpl::StartAgentTracing(
|
| + const base::trace_event::TraceConfig& trace_config) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + base::Closure on_start_tracing_done_callback =
|
| + base::Bind(&TracingControllerImpl::OnStartAgentTracingDone,
|
| + base::Unretained(this),
|
| + trace_config, start_tracing_done_callback_);
|
| + if (!BrowserThread::PostTask(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
|
| + base::Unretained(this), trace_config,
|
| + base::trace_event::TraceLog::RECORDING_MODE,
|
| + on_start_tracing_done_callback))) {
|
| + // BrowserThread::PostTask fails if the threads haven't been created yet,
|
| + // so it should be safe to just use TraceLog::SetEnabled directly.
|
| + base::trace_event::TraceLog::GetInstance()->SetEnabled(
|
| + trace_config, base::trace_event::TraceLog::RECORDING_MODE);
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| + on_start_tracing_done_callback);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void TracingControllerImpl::StopAgentTracing(
|
| + const StopAgentTracingCallback& callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + // Handle special case of zero child processes by immediately flushing the
|
| + // trace log. Once the flush has completed the caller will be notified that
|
| + // tracing has ended.
|
| + if (pending_stop_tracing_ack_count_ == 1) {
|
| + // Flush/cancel asynchronously now, because we don't have any children to
|
| + // wait for.
|
| + if (trace_data_sink_) {
|
| + TraceLog::GetInstance()->Flush(
|
| + base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
|
| + base::Unretained(this)),
|
| + true);
|
| + } else {
|
| + TraceLog::GetInstance()->CancelTracing(
|
| + base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
|
| + base::Unretained(this)));
|
| + }
|
| + }
|
| +
|
| + // Notify all child processes.
|
| + for (auto it : trace_message_filters_) {
|
| + if (trace_data_sink_)
|
| + it->SendEndTracing();
|
| + else
|
| + it->SendCancelTracing();
|
| + }
|
| +}
|
| +
|
| +bool TracingControllerImpl::SupportsExplicitClockSync() {
|
| + // TODO(zhenw): return true after implementing explicit clock sync.
|
| + return false;
|
| +}
|
| +
|
| +void TracingControllerImpl::RecordClockSyncMarker(
|
| + int sync_id,
|
| + const RecordClockSyncMarkerCallback& callback) {
|
| + DCHECK(SupportsExplicitClockSync());
|
| + // TODO(zhenw): implement explicit clock sync.
|
| +}
|
| +
|
| +void TracingControllerImpl::IssueClockSyncMarker() {
|
| + // TODO(zhenw): implement explicit clock sync.
|
| +}
|
| +
|
| void TracingControllerImpl::RequestGlobalMemoryDump(
|
| const base::trace_event::MemoryDumpRequestArgs& args,
|
| const base::trace_event::MemoryDumpCallback& callback) {
|
|
|