OLD | NEW |
---|---|
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" | |
13 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
14 #include "build/build_config.h" | 15 #include "build/build_config.h" |
15 #include "content/browser/tracing/file_tracing_provider_impl.h" | 16 #include "content/browser/tracing/file_tracing_provider_impl.h" |
16 #include "content/browser/tracing/power_tracing_agent.h" | 17 #include "content/browser/tracing/power_tracing_agent.h" |
17 #include "content/browser/tracing/trace_message_filter.h" | 18 #include "content/browser/tracing/trace_message_filter.h" |
18 #include "content/browser/tracing/tracing_ui.h" | 19 #include "content/browser/tracing/tracing_ui.h" |
19 #include "content/common/child_process_messages.h" | 20 #include "content/common/child_process_messages.h" |
20 #include "content/public/browser/browser_message_filter.h" | 21 #include "content/public/browser/browser_message_filter.h" |
21 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
22 #include "content/public/browser/gpu_data_manager.h" | 23 #include "content/public/browser/gpu_data_manager.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
43 | 44 |
44 namespace { | 45 namespace { |
45 | 46 |
46 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = | 47 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
47 LAZY_INSTANCE_INITIALIZER; | 48 LAZY_INSTANCE_INITIALIZER; |
48 | 49 |
49 const char kChromeTracingAgentName[] = "chrome"; | 50 const char kChromeTracingAgentName[] = "chrome"; |
50 const char kETWTracingAgentName[] = "etw"; | 51 const char kETWTracingAgentName[] = "etw"; |
51 const char kChromeTraceLabel[] = "traceEvents"; | 52 const char kChromeTraceLabel[] = "traceEvents"; |
52 | 53 |
54 const int kStartTracingTimeout = 30; | |
53 const int kIssueClockSyncTimeout = 30; | 55 const int kIssueClockSyncTimeout = 30; |
54 | 56 |
55 std::string GetNetworkTypeString() { | 57 std::string GetNetworkTypeString() { |
56 switch (net::NetworkChangeNotifier::GetConnectionType()) { | 58 switch (net::NetworkChangeNotifier::GetConnectionType()) { |
57 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: | 59 case net::NetworkChangeNotifier::CONNECTION_ETHERNET: |
58 return "Ethernet"; | 60 return "Ethernet"; |
59 case net::NetworkChangeNotifier::CONNECTION_WIFI: | 61 case net::NetworkChangeNotifier::CONNECTION_WIFI: |
60 return "WiFi"; | 62 return "WiFi"; |
61 case net::NetworkChangeNotifier::CONNECTION_2G: | 63 case net::NetworkChangeNotifier::CONNECTION_2G: |
62 return "2G"; | 64 return "2G"; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 return metadata_dict; | 139 return metadata_dict; |
138 } | 140 } |
139 | 141 |
140 } // namespace | 142 } // namespace |
141 | 143 |
142 TracingController* TracingController::GetInstance() { | 144 TracingController* TracingController::GetInstance() { |
143 return TracingControllerImpl::GetInstance(); | 145 return TracingControllerImpl::GetInstance(); |
144 } | 146 } |
145 | 147 |
146 TracingControllerImpl::TracingControllerImpl() | 148 TracingControllerImpl::TracingControllerImpl() |
147 : pending_stop_tracing_ack_count_(0), | 149 : pending_start_tracing_ack_count_(0), |
150 pending_stop_tracing_ack_count_(0), | |
148 pending_capture_monitoring_snapshot_ack_count_(0), | 151 pending_capture_monitoring_snapshot_ack_count_(0), |
149 pending_trace_log_status_ack_count_(0), | 152 pending_trace_log_status_ack_count_(0), |
150 maximum_trace_buffer_usage_(0), | 153 maximum_trace_buffer_usage_(0), |
151 approximate_event_count_(0), | 154 approximate_event_count_(0), |
152 pending_memory_dump_ack_count_(0), | 155 pending_memory_dump_ack_count_(0), |
153 failed_memory_dump_count_(0), | 156 failed_memory_dump_count_(0), |
154 clock_sync_id_(0), | 157 clock_sync_id_(0), |
155 pending_clock_sync_ack_count_(0), | 158 pending_clock_sync_ack_count_(0), |
156 is_tracing_(false), | 159 is_tracing_(false), |
157 is_monitoring_(false) { | 160 is_monitoring_(false) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 bool TracingControllerImpl::StartTracing( | 214 bool TracingControllerImpl::StartTracing( |
212 const TraceConfig& trace_config, | 215 const TraceConfig& trace_config, |
213 const StartTracingDoneCallback& callback) { | 216 const StartTracingDoneCallback& callback) { |
214 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 217 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
215 DCHECK(additional_tracing_agents_.empty()); | 218 DCHECK(additional_tracing_agents_.empty()); |
216 | 219 |
217 if (!can_start_tracing()) | 220 if (!can_start_tracing()) |
218 return false; | 221 return false; |
219 is_tracing_ = true; | 222 is_tracing_ = true; |
220 start_tracing_done_callback_ = callback; | 223 start_tracing_done_callback_ = callback; |
224 start_tracing_trace_config_.reset( | |
225 new base::trace_event::TraceConfig(trace_config)); | |
226 pending_start_tracing_ack_count_ = 0; | |
221 | 227 |
222 #if defined(OS_ANDROID) | 228 #if defined(OS_ANDROID) |
223 if (pending_get_categories_done_callback_.is_null()) | 229 if (pending_get_categories_done_callback_.is_null()) |
224 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 230 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
225 #endif | 231 #endif |
226 | 232 |
227 if (trace_config.IsSystraceEnabled()) { | 233 if (trace_config.IsSystraceEnabled()) { |
228 if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config)) | 234 PowerTracingAgent::GetInstance()->StartAgentTracing( |
229 additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance()); | 235 trace_config, |
236 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, | |
237 base::Unretained(this))); | |
238 ++pending_start_tracing_ack_count_; | |
239 | |
230 #if defined(OS_CHROMEOS) | 240 #if defined(OS_CHROMEOS) |
231 chromeos::DebugDaemonClient* debug_daemon = | 241 chromeos::DebugDaemonClient* debug_daemon = |
232 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | 242 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); |
233 if (debug_daemon && debug_daemon->StartAgentTracing(trace_config)) { | 243 if (debug_daemon) { |
234 debug_daemon->SetStopAgentTracingTaskRunner( | 244 debug_daemon->StartAgentTracing( |
235 BrowserThread::GetBlockingPool()); | 245 trace_config, |
236 additional_tracing_agents_.push_back( | 246 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, |
237 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()); | 247 base::Unretained(this))); |
248 ++pending_start_tracing_ack_count_; | |
238 } | 249 } |
239 #elif defined(OS_WIN) | 250 #elif defined(OS_WIN) |
240 if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing( | 251 EtwSystemEventConsumer::GetInstance()->StartAgentTracing( |
241 trace_config)) { | 252 trace_config, |
242 additional_tracing_agents_.push_back( | 253 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, |
243 EtwSystemEventConsumer::GetInstance()); | 254 base::Unretained(this))); |
244 } | 255 ++pending_start_tracing_ack_count_; |
245 #endif | 256 #endif |
246 } | 257 } |
247 | 258 |
248 // TraceLog may have been enabled in startup tracing before threads are ready. | 259 // TraceLog may have been enabled in startup tracing before threads are ready. |
249 if (TraceLog::GetInstance()->IsEnabled()) | 260 if (TraceLog::GetInstance()->IsEnabled()) |
250 return true; | 261 return true; |
251 return StartAgentTracing(trace_config); | 262 |
263 StartAgentTracing(trace_config, | |
264 base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, | |
265 base::Unretained(this))); | |
266 ++pending_start_tracing_ack_count_; | |
267 | |
268 // Set a deadline to ensure all agents ack within a reasonable time frame. | |
269 start_tracing_timer_.Start( | |
270 FROM_HERE, base::TimeDelta::FromSeconds(kStartTracingTimeout), | |
271 base::Bind(&TracingControllerImpl::OnAllTracingAgentsStarted, | |
272 base::Unretained(this))); | |
273 | |
274 return true; | |
252 } | 275 } |
253 | 276 |
254 void TracingControllerImpl::OnStartAgentTracingDone( | 277 void TracingControllerImpl::OnAllTracingAgentsStarted() { |
255 const TraceConfig& trace_config) { | |
256 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 278 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
257 | 279 |
258 TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value", | 280 TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value", |
259 base::TimeTicks::IsHighResolution()); | 281 base::TimeTicks::IsHighResolution()); |
260 TRACE_EVENT_API_ADD_METADATA_EVENT("TraceConfig", "value", | 282 TRACE_EVENT_API_ADD_METADATA_EVENT( |
261 trace_config.AsConvertableToTraceFormat()); | 283 "TraceConfig", "value", |
284 start_tracing_trace_config_->AsConvertableToTraceFormat()); | |
262 | 285 |
263 // Notify all child processes. | 286 // Notify all child processes. |
264 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 287 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
265 it != trace_message_filters_.end(); ++it) { | 288 it != trace_message_filters_.end(); ++it) { |
266 it->get()->SendBeginTracing(trace_config); | 289 it->get()->SendBeginTracing(*start_tracing_trace_config_); |
267 } | 290 } |
268 | 291 |
269 if (!start_tracing_done_callback_.is_null()) { | 292 if (!start_tracing_done_callback_.is_null()) |
270 start_tracing_done_callback_.Run(); | 293 start_tracing_done_callback_.Run(); |
271 start_tracing_done_callback_.Reset(); | 294 |
272 } | 295 start_tracing_done_callback_.Reset(); |
296 start_tracing_trace_config_.reset(); | |
273 } | 297 } |
274 | 298 |
275 bool TracingControllerImpl::StopTracing( | 299 bool TracingControllerImpl::StopTracing( |
276 const scoped_refptr<TraceDataSink>& trace_data_sink) { | 300 const scoped_refptr<TraceDataSink>& trace_data_sink) { |
277 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 301 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
278 | 302 |
279 if (trace_data_sink) { | 303 if (trace_data_sink) { |
280 if (TraceLog::GetInstance()->GetCurrentTraceConfig() | 304 if (TraceLog::GetInstance()->GetCurrentTraceConfig() |
281 .IsArgumentFilterEnabled()) { | 305 .IsArgumentFilterEnabled()) { |
282 scoped_ptr<TracingDelegate> delegate( | 306 scoped_ptr<TracingDelegate> delegate( |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
629 BrowserThread::UI, FROM_HERE, | 653 BrowserThread::UI, FROM_HERE, |
630 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse, | 654 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse, |
631 base::Unretained(this), | 655 base::Unretained(this), |
632 make_scoped_refptr(trace_message_filter), | 656 make_scoped_refptr(trace_message_filter), |
633 pending_memory_dump_guid_, false /* success */)); | 657 pending_memory_dump_guid_, false /* success */)); |
634 } | 658 } |
635 } | 659 } |
636 trace_message_filters_.erase(trace_message_filter); | 660 trace_message_filters_.erase(trace_message_filter); |
637 } | 661 } |
638 | 662 |
663 void TracingControllerImpl::AddTracingAgent(const std::string& agent_name) { | |
664 #if defined(OS_CHROMEOS) | |
665 auto debug_daemon = | |
666 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | |
667 if (agent_name == debug_daemon->GetTracingAgentName()) { | |
668 additional_tracing_agents_.push_back(debug_daemon); | |
669 debug_daemon->SetStopAgentTracingTaskRunner( | |
670 BrowserThread::GetBlockingPool()); | |
671 return; | |
672 } | |
673 #elif defined(OS_WIN) | |
674 auto etw_agent = EtwSystemEventConsumer::GetInstance(); | |
675 if (agent_name == etw_agent->GetTracingAgentName()) { | |
676 additional_tracing_agents_.push_back(etw_agent); | |
677 return; | |
678 } | |
679 #endif | |
680 | |
681 auto power_agent = PowerTracingAgent::GetInstance(); | |
682 if (agent_name == power_agent->GetTracingAgentName()) { | |
683 additional_tracing_agents_.push_back(power_agent); | |
684 return; | |
685 } | |
686 | |
687 DCHECK(agent_name == kChromeTracingAgentName); | |
688 } | |
689 | |
690 void TracingControllerImpl::OnStartAgentTracingAcked( | |
oystein (OOO til 10th of July)
2016/01/25 22:19:41
What happens if StopTracing() gets called before a
charliea (OOO until 10-5)
2016/01/26 00:30:09
One thing that we could do is, when StopTracing is
| |
691 const std::string& agent_name, | |
692 bool success) { | |
693 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
694 | |
695 // Don't taken any further action if the ack came after the deadline. | |
696 if (!start_tracing_timer_.IsRunning()) | |
697 return; | |
698 | |
699 if (success) | |
700 AddTracingAgent(agent_name); | |
701 | |
702 if (--pending_start_tracing_ack_count_ == 0) { | |
703 start_tracing_timer_.Stop(); | |
704 OnAllTracingAgentsStarted(); | |
705 } | |
706 } | |
707 | |
639 void TracingControllerImpl::OnStopTracingAcked( | 708 void TracingControllerImpl::OnStopTracingAcked( |
640 TraceMessageFilter* trace_message_filter, | 709 TraceMessageFilter* trace_message_filter, |
641 const std::vector<std::string>& known_category_groups) { | 710 const std::vector<std::string>& known_category_groups) { |
642 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 711 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
643 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 712 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
644 base::Bind(&TracingControllerImpl::OnStopTracingAcked, | 713 base::Bind(&TracingControllerImpl::OnStopTracingAcked, |
645 base::Unretained(this), | 714 base::Unretained(this), |
646 make_scoped_refptr(trace_message_filter), | 715 make_scoped_refptr(trace_message_filter), |
647 known_category_groups)); | 716 known_category_groups)); |
648 return; | 717 return; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
869 } | 938 } |
870 | 939 |
871 std::string TracingControllerImpl::GetTracingAgentName() { | 940 std::string TracingControllerImpl::GetTracingAgentName() { |
872 return kChromeTracingAgentName; | 941 return kChromeTracingAgentName; |
873 } | 942 } |
874 | 943 |
875 std::string TracingControllerImpl::GetTraceEventLabel() { | 944 std::string TracingControllerImpl::GetTraceEventLabel() { |
876 return kChromeTraceLabel; | 945 return kChromeTraceLabel; |
877 } | 946 } |
878 | 947 |
879 bool TracingControllerImpl::StartAgentTracing( | 948 void TracingControllerImpl::StartAgentTracing( |
880 const base::trace_event::TraceConfig& trace_config) { | 949 const base::trace_event::TraceConfig& trace_config, |
950 const StartAgentTracingCallback& callback) { | |
881 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 951 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
882 | 952 |
883 base::Closure on_start_tracing_done_callback = | 953 base::Closure on_agent_started = |
884 base::Bind(&TracingControllerImpl::OnStartAgentTracingDone, | 954 base::Bind(callback, kChromeTracingAgentName, true); |
885 base::Unretained(this), trace_config); | |
886 if (!BrowserThread::PostTask( | 955 if (!BrowserThread::PostTask( |
887 BrowserThread::FILE, FROM_HERE, | 956 BrowserThread::FILE, FROM_HERE, |
888 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, | 957 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
889 base::Unretained(this), trace_config, | 958 base::Unretained(this), trace_config, |
890 base::trace_event::TraceLog::RECORDING_MODE, | 959 base::trace_event::TraceLog::RECORDING_MODE, |
891 on_start_tracing_done_callback))) { | 960 on_agent_started))) { |
892 // BrowserThread::PostTask fails if the threads haven't been created yet, | 961 // BrowserThread::PostTask fails if the threads haven't been created yet, |
893 // so it should be safe to just use TraceLog::SetEnabled directly. | 962 // so it should be safe to just use TraceLog::SetEnabled directly. |
894 base::trace_event::TraceLog::GetInstance()->SetEnabled( | 963 base::trace_event::TraceLog::GetInstance()->SetEnabled( |
895 trace_config, base::trace_event::TraceLog::RECORDING_MODE); | 964 trace_config, base::trace_event::TraceLog::RECORDING_MODE); |
896 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 965 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_agent_started); |
897 on_start_tracing_done_callback); | |
898 } | 966 } |
899 | |
900 return true; | |
901 } | 967 } |
902 | 968 |
903 void TracingControllerImpl::StopAgentTracing( | 969 void TracingControllerImpl::StopAgentTracing( |
904 const StopAgentTracingCallback& callback) { | 970 const StopAgentTracingCallback& callback) { |
905 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 971 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
906 // Handle special case of zero child processes by immediately flushing the | 972 // Handle special case of zero child processes by immediately flushing the |
907 // trace log. Once the flush has completed the caller will be notified that | 973 // trace log. Once the flush has completed the caller will be notified that |
908 // tracing has ended. | 974 // tracing has ended. |
909 if (pending_stop_tracing_ack_count_ == 1) { | 975 if (pending_stop_tracing_ack_count_ == 1) { |
910 // Flush/cancel asynchronously now, because we don't have any children to | 976 // Flush/cancel asynchronously now, because we don't have any children to |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1123 is_monitoring_ = is_monitoring; | 1189 is_monitoring_ = is_monitoring; |
1124 #if !defined(OS_ANDROID) | 1190 #if !defined(OS_ANDROID) |
1125 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); | 1191 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); |
1126 it != tracing_uis_.end(); it++) { | 1192 it != tracing_uis_.end(); it++) { |
1127 (*it)->OnMonitoringStateChanged(is_monitoring); | 1193 (*it)->OnMonitoringStateChanged(is_monitoring); |
1128 } | 1194 } |
1129 #endif | 1195 #endif |
1130 } | 1196 } |
1131 | 1197 |
1132 } // namespace content | 1198 } // namespace content |
OLD | NEW |