Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: content/browser/tracing/tracing_controller_impl.cc

Issue 1614063005: Adds a callback to TracingAgent::StartAgentTracing() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 #include "content/browser/tracing/tracing_controller_impl.h" 4 #include "content/browser/tracing/tracing_controller_impl.h"
5 5
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/cpu.h" 7 #include "base/cpu.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/json/string_escape.h" 9 #include "base/json/string_escape.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/sys_info.h" 12 #include "base/sys_info.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/time/time.h"
13 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
14 #include "build/build_config.h" 16 #include "build/build_config.h"
15 #include "components/tracing/process_metrics_memory_dump_provider.h" 17 #include "components/tracing/process_metrics_memory_dump_provider.h"
16 #include "content/browser/tracing/file_tracing_provider_impl.h" 18 #include "content/browser/tracing/file_tracing_provider_impl.h"
17 #include "content/browser/tracing/power_tracing_agent.h" 19 #include "content/browser/tracing/power_tracing_agent.h"
18 #include "content/browser/tracing/trace_message_filter.h" 20 #include "content/browser/tracing/trace_message_filter.h"
19 #include "content/browser/tracing/tracing_ui.h" 21 #include "content/browser/tracing/tracing_ui.h"
20 #include "content/common/child_process_messages.h" 22 #include "content/common/child_process_messages.h"
21 #include "content/public/browser/browser_message_filter.h" 23 #include "content/public/browser/browser_message_filter.h"
22 #include "content/public/browser/content_browser_client.h" 24 #include "content/public/browser/content_browser_client.h"
(...skipping 21 matching lines...) Expand all
44 46
45 namespace { 47 namespace {
46 48
47 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = 49 base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
48 LAZY_INSTANCE_INITIALIZER; 50 LAZY_INSTANCE_INITIALIZER;
49 51
50 const char kChromeTracingAgentName[] = "chrome"; 52 const char kChromeTracingAgentName[] = "chrome";
51 const char kETWTracingAgentName[] = "etw"; 53 const char kETWTracingAgentName[] = "etw";
52 const char kChromeTraceLabel[] = "traceEvents"; 54 const char kChromeTraceLabel[] = "traceEvents";
53 55
56 const int kStartTracingTimeoutSeconds = 30;
54 const int kIssueClockSyncTimeoutSeconds = 30; 57 const int kIssueClockSyncTimeoutSeconds = 30;
58 const int kStopTracingRetryTimeMilliseconds = 100;
55 59
56 std::string GetNetworkTypeString() { 60 std::string GetNetworkTypeString() {
57 switch (net::NetworkChangeNotifier::GetConnectionType()) { 61 switch (net::NetworkChangeNotifier::GetConnectionType()) {
58 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: 62 case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
59 return "Ethernet"; 63 return "Ethernet";
60 case net::NetworkChangeNotifier::CONNECTION_WIFI: 64 case net::NetworkChangeNotifier::CONNECTION_WIFI:
61 return "WiFi"; 65 return "WiFi";
62 case net::NetworkChangeNotifier::CONNECTION_2G: 66 case net::NetworkChangeNotifier::CONNECTION_2G:
63 return "2G"; 67 return "2G";
64 case net::NetworkChangeNotifier::CONNECTION_3G: 68 case net::NetworkChangeNotifier::CONNECTION_3G:
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 return metadata_dict; 142 return metadata_dict;
139 } 143 }
140 144
141 } // namespace 145 } // namespace
142 146
143 TracingController* TracingController::GetInstance() { 147 TracingController* TracingController::GetInstance() {
144 return TracingControllerImpl::GetInstance(); 148 return TracingControllerImpl::GetInstance();
145 } 149 }
146 150
147 TracingControllerImpl::TracingControllerImpl() 151 TracingControllerImpl::TracingControllerImpl()
148 : pending_stop_tracing_ack_count_(0), 152 : pending_start_tracing_ack_count_(0),
153 pending_stop_tracing_ack_count_(0),
149 pending_capture_monitoring_snapshot_ack_count_(0), 154 pending_capture_monitoring_snapshot_ack_count_(0),
150 pending_trace_log_status_ack_count_(0), 155 pending_trace_log_status_ack_count_(0),
151 maximum_trace_buffer_usage_(0), 156 maximum_trace_buffer_usage_(0),
152 approximate_event_count_(0), 157 approximate_event_count_(0),
153 pending_memory_dump_ack_count_(0), 158 pending_memory_dump_ack_count_(0),
154 failed_memory_dump_count_(0), 159 failed_memory_dump_count_(0),
155 clock_sync_id_(0), 160 clock_sync_id_(0),
156 pending_clock_sync_ack_count_(0), 161 pending_clock_sync_ack_count_(0),
157 is_tracing_(false), 162 is_tracing_(false),
158 is_monitoring_(false) { 163 is_monitoring_(false) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 bool TracingControllerImpl::StartTracing( 217 bool TracingControllerImpl::StartTracing(
213 const TraceConfig& trace_config, 218 const TraceConfig& trace_config,
214 const StartTracingDoneCallback& callback) { 219 const StartTracingDoneCallback& callback) {
215 DCHECK_CURRENTLY_ON(BrowserThread::UI); 220 DCHECK_CURRENTLY_ON(BrowserThread::UI);
216 DCHECK(additional_tracing_agents_.empty()); 221 DCHECK(additional_tracing_agents_.empty());
217 222
218 if (!can_start_tracing()) 223 if (!can_start_tracing())
219 return false; 224 return false;
220 is_tracing_ = true; 225 is_tracing_ = true;
221 start_tracing_done_callback_ = callback; 226 start_tracing_done_callback_ = callback;
227 start_tracing_trace_config_.reset(
228 new base::trace_event::TraceConfig(trace_config));
229 pending_start_tracing_ack_count_ = 0;
222 230
223 #if defined(OS_ANDROID) 231 #if defined(OS_ANDROID)
224 if (pending_get_categories_done_callback_.is_null()) 232 if (pending_get_categories_done_callback_.is_null())
225 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); 233 TraceLog::GetInstance()->AddClockSyncMetadataEvent();
226 #endif 234 #endif
227 235
228 if (trace_config.IsSystraceEnabled()) { 236 if (trace_config.IsSystraceEnabled()) {
229 if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config)) 237 PowerTracingAgent::GetInstance()->StartAgentTracing(
230 additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance()); 238 trace_config,
239 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
240 base::Unretained(this)));
241 ++pending_start_tracing_ack_count_;
242
231 #if defined(OS_CHROMEOS) 243 #if defined(OS_CHROMEOS)
232 chromeos::DebugDaemonClient* debug_daemon = 244 chromeos::DebugDaemonClient* debug_daemon =
233 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); 245 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
234 if (debug_daemon && debug_daemon->StartAgentTracing(trace_config)) { 246 if (debug_daemon) {
235 debug_daemon->SetStopAgentTracingTaskRunner( 247 debug_daemon->StartAgentTracing(
236 BrowserThread::GetBlockingPool()); 248 trace_config,
237 additional_tracing_agents_.push_back( 249 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
238 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()); 250 base::Unretained(this)));
251 ++pending_start_tracing_ack_count_;
239 } 252 }
240 #elif defined(OS_WIN) 253 #elif defined(OS_WIN)
241 if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing( 254 EtwSystemEventConsumer::GetInstance()->StartAgentTracing(
242 trace_config)) { 255 trace_config,
243 additional_tracing_agents_.push_back( 256 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
244 EtwSystemEventConsumer::GetInstance()); 257 base::Unretained(this)));
245 } 258 ++pending_start_tracing_ack_count_;
246 #endif 259 #endif
247 } 260 }
248 261
249 // TraceLog may have been enabled in startup tracing before threads are ready. 262 // TraceLog may have been enabled in startup tracing before threads are ready.
250 if (TraceLog::GetInstance()->IsEnabled()) 263 if (TraceLog::GetInstance()->IsEnabled())
251 return true; 264 return true;
252 return StartAgentTracing(trace_config); 265
266 StartAgentTracing(trace_config,
267 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked,
268 base::Unretained(this)));
269 ++pending_start_tracing_ack_count_;
270
271 // Set a deadline to ensure all agents ack within a reasonable time frame.
272 start_tracing_timer_.Start(
273 FROM_HERE, base::TimeDelta::FromSeconds(kStartTracingTimeoutSeconds),
274 base::Bind(&TracingControllerImpl::OnAllTracingAgentsStarted,
275 base::Unretained(this)));
276
277 return true;
253 } 278 }
254 279
255 void TracingControllerImpl::OnStartAgentTracingDone( 280 void TracingControllerImpl::OnAllTracingAgentsStarted() {
256 const TraceConfig& trace_config) {
257 DCHECK_CURRENTLY_ON(BrowserThread::UI); 281 DCHECK_CURRENTLY_ON(BrowserThread::UI);
258 282
259 TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value", 283 TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value",
260 base::TimeTicks::IsHighResolution()); 284 base::TimeTicks::IsHighResolution());
261 TRACE_EVENT_API_ADD_METADATA_EVENT("TraceConfig", "value", 285 TRACE_EVENT_API_ADD_METADATA_EVENT(
262 trace_config.AsConvertableToTraceFormat()); 286 "TraceConfig", "value",
287 start_tracing_trace_config_->AsConvertableToTraceFormat());
263 288
264 // Notify all child processes. 289 // Notify all child processes.
265 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); 290 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
266 it != trace_message_filters_.end(); ++it) { 291 it != trace_message_filters_.end(); ++it) {
267 it->get()->SendBeginTracing(trace_config); 292 it->get()->SendBeginTracing(*start_tracing_trace_config_);
268 } 293 }
269 294
270 if (!start_tracing_done_callback_.is_null()) { 295 if (!start_tracing_done_callback_.is_null())
271 start_tracing_done_callback_.Run(); 296 start_tracing_done_callback_.Run();
272 start_tracing_done_callback_.Reset(); 297
273 } 298 start_tracing_done_callback_.Reset();
299 start_tracing_trace_config_.reset();
274 } 300 }
275 301
276 bool TracingControllerImpl::StopTracing( 302 bool TracingControllerImpl::StopTracing(
277 const scoped_refptr<TraceDataSink>& trace_data_sink) { 303 const scoped_refptr<TraceDataSink>& trace_data_sink) {
278 DCHECK_CURRENTLY_ON(BrowserThread::UI); 304 DCHECK_CURRENTLY_ON(BrowserThread::UI);
279 305
306 if (!can_stop_tracing())
307 return false;
308
309 // If we're still waiting to start tracing, try again after a delay.
310 if (start_tracing_timer_.IsRunning()) {
311 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
312 FROM_HERE,
313 base::Bind(base::IgnoreResult(&TracingControllerImpl::StopTracing),
314 base::Unretained(this), trace_data_sink),
315 base::TimeDelta::FromMilliseconds(kStopTracingRetryTimeMilliseconds));
316 return true;
317 }
318
280 if (trace_data_sink) { 319 if (trace_data_sink) {
281 if (TraceLog::GetInstance()->GetCurrentTraceConfig() 320 if (TraceLog::GetInstance()->GetCurrentTraceConfig()
282 .IsArgumentFilterEnabled()) { 321 .IsArgumentFilterEnabled()) {
283 scoped_ptr<TracingDelegate> delegate( 322 scoped_ptr<TracingDelegate> delegate(
284 GetContentClient()->browser()->GetTracingDelegate()); 323 GetContentClient()->browser()->GetTracingDelegate());
285 if (delegate) { 324 if (delegate) {
286 trace_data_sink->SetMetadataFilterPredicate( 325 trace_data_sink->SetMetadataFilterPredicate(
287 delegate->GetMetadataFilterPredicate()); 326 delegate->GetMetadataFilterPredicate());
288 } 327 }
289 } 328 }
290 trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get()); 329 trace_data_sink->AddMetadata(*GenerateTracingMetadataDict().get());
291 } 330 }
292 331
293 if (!can_stop_tracing())
294 return false;
295
296 trace_data_sink_ = trace_data_sink; 332 trace_data_sink_ = trace_data_sink;
297 333
298 // Issue clock sync marker before actually stopping tracing. 334 // Issue clock sync marker before actually stopping tracing.
299 // StopTracingAfterClockSync() will be called after clock sync is done. 335 // StopTracingAfterClockSync() will be called after clock sync is done.
300 IssueClockSyncMarker(); 336 IssueClockSyncMarker();
301 337
302 return true; 338 return true;
303 } 339 }
304 340
305 void TracingControllerImpl::StopTracingAfterClockSync() { 341 void TracingControllerImpl::StopTracingAfterClockSync() {
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 BrowserThread::UI, FROM_HERE, 678 BrowserThread::UI, FROM_HERE,
643 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse, 679 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse,
644 base::Unretained(this), 680 base::Unretained(this),
645 make_scoped_refptr(trace_message_filter), 681 make_scoped_refptr(trace_message_filter),
646 pending_memory_dump_guid_, false /* success */)); 682 pending_memory_dump_guid_, false /* success */));
647 } 683 }
648 } 684 }
649 trace_message_filters_.erase(trace_message_filter); 685 trace_message_filters_.erase(trace_message_filter);
650 } 686 }
651 687
688 void TracingControllerImpl::AddTracingAgent(const std::string& agent_name) {
689 #if defined(OS_CHROMEOS)
690 auto debug_daemon =
691 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
692 if (agent_name == debug_daemon->GetTracingAgentName()) {
693 additional_tracing_agents_.push_back(debug_daemon);
694 debug_daemon->SetStopAgentTracingTaskRunner(
695 BrowserThread::GetBlockingPool());
696 return;
697 }
698 #elif defined(OS_WIN)
699 auto etw_agent = EtwSystemEventConsumer::GetInstance();
700 if (agent_name == etw_agent->GetTracingAgentName()) {
701 additional_tracing_agents_.push_back(etw_agent);
702 return;
703 }
704 #endif
705
706 auto power_agent = PowerTracingAgent::GetInstance();
707 if (agent_name == power_agent->GetTracingAgentName()) {
708 additional_tracing_agents_.push_back(power_agent);
709 return;
710 }
711
712 DCHECK(agent_name == kChromeTracingAgentName);
713 }
714
715 void TracingControllerImpl::OnStartAgentTracingAcked(
716 const std::string& agent_name,
717 bool success) {
718 DCHECK_CURRENTLY_ON(BrowserThread::UI);
719
720 // Don't taken any further action if the ack came after the deadline.
721 if (!start_tracing_timer_.IsRunning())
722 return;
723
724 if (success)
725 AddTracingAgent(agent_name);
726
727 if (--pending_start_tracing_ack_count_ == 0) {
728 start_tracing_timer_.Stop();
729 OnAllTracingAgentsStarted();
730 }
731 }
732
652 void TracingControllerImpl::OnStopTracingAcked( 733 void TracingControllerImpl::OnStopTracingAcked(
653 TraceMessageFilter* trace_message_filter, 734 TraceMessageFilter* trace_message_filter,
654 const std::vector<std::string>& known_category_groups) { 735 const std::vector<std::string>& known_category_groups) {
655 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 736 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
656 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 737 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
657 base::Bind(&TracingControllerImpl::OnStopTracingAcked, 738 base::Bind(&TracingControllerImpl::OnStopTracingAcked,
658 base::Unretained(this), 739 base::Unretained(this),
659 make_scoped_refptr(trace_message_filter), 740 make_scoped_refptr(trace_message_filter),
660 known_category_groups)); 741 known_category_groups));
661 return; 742 return;
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 } 964 }
884 965
885 std::string TracingControllerImpl::GetTracingAgentName() { 966 std::string TracingControllerImpl::GetTracingAgentName() {
886 return kChromeTracingAgentName; 967 return kChromeTracingAgentName;
887 } 968 }
888 969
889 std::string TracingControllerImpl::GetTraceEventLabel() { 970 std::string TracingControllerImpl::GetTraceEventLabel() {
890 return kChromeTraceLabel; 971 return kChromeTraceLabel;
891 } 972 }
892 973
893 bool TracingControllerImpl::StartAgentTracing( 974 void TracingControllerImpl::StartAgentTracing(
894 const base::trace_event::TraceConfig& trace_config) { 975 const base::trace_event::TraceConfig& trace_config,
976 const StartAgentTracingCallback& callback) {
895 DCHECK_CURRENTLY_ON(BrowserThread::UI); 977 DCHECK_CURRENTLY_ON(BrowserThread::UI);
896 978
897 base::Closure on_start_tracing_done_callback = 979 base::Closure on_agent_started =
898 base::Bind(&TracingControllerImpl::OnStartAgentTracingDone, 980 base::Bind(callback, kChromeTracingAgentName, true);
899 base::Unretained(this), trace_config);
900 if (!BrowserThread::PostTask( 981 if (!BrowserThread::PostTask(
901 BrowserThread::FILE, FROM_HERE, 982 BrowserThread::FILE, FROM_HERE,
902 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, 983 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
903 base::Unretained(this), trace_config, 984 base::Unretained(this), trace_config,
904 base::trace_event::TraceLog::RECORDING_MODE, 985 base::trace_event::TraceLog::RECORDING_MODE,
905 on_start_tracing_done_callback))) { 986 on_agent_started))) {
906 // BrowserThread::PostTask fails if the threads haven't been created yet, 987 // BrowserThread::PostTask fails if the threads haven't been created yet,
907 // so it should be safe to just use TraceLog::SetEnabled directly. 988 // so it should be safe to just use TraceLog::SetEnabled directly.
908 base::trace_event::TraceLog::GetInstance()->SetEnabled( 989 base::trace_event::TraceLog::GetInstance()->SetEnabled(
909 trace_config, base::trace_event::TraceLog::RECORDING_MODE); 990 trace_config, base::trace_event::TraceLog::RECORDING_MODE);
910 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 991 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_agent_started);
911 on_start_tracing_done_callback);
912 } 992 }
913
914 return true;
915 } 993 }
916 994
917 void TracingControllerImpl::StopAgentTracing( 995 void TracingControllerImpl::StopAgentTracing(
918 const StopAgentTracingCallback& callback) { 996 const StopAgentTracingCallback& callback) {
919 DCHECK_CURRENTLY_ON(BrowserThread::UI); 997 DCHECK_CURRENTLY_ON(BrowserThread::UI);
920 // Handle special case of zero child processes by immediately flushing the 998 // Handle special case of zero child processes by immediately flushing the
921 // trace log. Once the flush has completed the caller will be notified that 999 // trace log. Once the flush has completed the caller will be notified that
922 // tracing has ended. 1000 // tracing has ended.
923 if (pending_stop_tracing_ack_count_ == 1) { 1001 if (pending_stop_tracing_ack_count_ == 1) {
924 // Flush/cancel asynchronously now, because we don't have any children to 1002 // Flush/cancel asynchronously now, because we don't have any children to
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 is_monitoring_ = is_monitoring; 1213 is_monitoring_ = is_monitoring;
1136 #if !defined(OS_ANDROID) 1214 #if !defined(OS_ANDROID)
1137 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); 1215 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin();
1138 it != tracing_uis_.end(); it++) { 1216 it != tracing_uis_.end(); it++) {
1139 (*it)->OnMonitoringStateChanged(is_monitoring); 1217 (*it)->OnMonitoringStateChanged(is_monitoring);
1140 } 1218 }
1141 #endif 1219 #endif
1142 } 1220 }
1143 1221
1144 } // namespace content 1222 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698