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/files/file_util.h" | 7 #include "base/files/file_util.h" |
8 #include "base/json/string_escape.h" | 8 #include "base/json/string_escape.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
12 #include "content/browser/tracing/file_tracing_provider_impl.h" | 12 #include "content/browser/tracing/file_tracing_provider_impl.h" |
13 #include "content/browser/tracing/trace_message_filter.h" | 13 #include "content/browser/tracing/trace_message_filter.h" |
14 #include "content/browser/tracing/tracing_ui.h" | 14 #include "content/browser/tracing/tracing_ui.h" |
15 #include "content/common/child_process_messages.h" | 15 #include "content/common/child_process_messages.h" |
16 #include "content/public/browser/browser_message_filter.h" | 16 #include "content/public/browser/browser_message_filter.h" |
17 #include "content/public/common/content_switches.h" | 17 #include "content/public/common/content_switches.h" |
18 | 18 |
19 #if defined(OS_CHROMEOS) | 19 #if defined(OS_CHROMEOS) |
20 #include "chromeos/dbus/dbus_thread_manager.h" | 20 #include "chromeos/dbus/dbus_thread_manager.h" |
21 #include "chromeos/dbus/debug_daemon_client.h" | 21 #include "chromeos/dbus/debug_daemon_client.h" |
22 #endif | 22 #endif |
23 | 23 |
24 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
25 #include "content/browser/tracing/etw_system_event_consumer_win.h" | 25 #include "content/browser/tracing/etw_system_event_consumer_win.h" |
26 #endif | 26 #endif |
27 | 27 |
28 using base::trace_event::TraceLog; | 28 using base::trace_event::TraceLog; |
29 using base::trace_event::TraceOptions; | 29 using base::trace_event::TraceConfig; |
30 using base::trace_event::CategoryFilter; | |
31 | 30 |
32 namespace content { | 31 namespace content { |
33 | 32 |
34 namespace { | 33 namespace { |
35 | 34 |
36 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = | 35 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
37 LAZY_INSTANCE_INITIALIZER; | 36 LAZY_INSTANCE_INITIALIZER; |
38 | 37 |
39 } // namespace | 38 } // namespace |
40 | 39 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 } | 72 } |
74 | 73 |
75 bool TracingControllerImpl::GetCategories( | 74 bool TracingControllerImpl::GetCategories( |
76 const GetCategoriesDoneCallback& callback) { | 75 const GetCategoriesDoneCallback& callback) { |
77 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 76 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
78 | 77 |
79 // Known categories come back from child processes with the EndTracingAck | 78 // Known categories come back from child processes with the EndTracingAck |
80 // message. So to get known categories, just begin and end tracing immediately | 79 // message. So to get known categories, just begin and end tracing immediately |
81 // afterwards. This will ping all the child processes for categories. | 80 // afterwards. This will ping all the child processes for categories. |
82 pending_get_categories_done_callback_ = callback; | 81 pending_get_categories_done_callback_ = callback; |
83 if (!EnableRecording( | 82 if (!EnableRecording(TraceConfig("*", ""), EnableRecordingDoneCallback())) { |
84 CategoryFilter("*"), TraceOptions(), EnableRecordingDoneCallback())) { | |
85 pending_get_categories_done_callback_.Reset(); | 83 pending_get_categories_done_callback_.Reset(); |
86 return false; | 84 return false; |
87 } | 85 } |
88 | 86 |
89 bool ok = DisableRecording(NULL); | 87 bool ok = DisableRecording(NULL); |
90 DCHECK(ok); | 88 DCHECK(ok); |
91 return true; | 89 return true; |
92 } | 90 } |
93 | 91 |
94 void TracingControllerImpl::SetEnabledOnFileThread( | 92 void TracingControllerImpl::SetEnabledOnFileThread( |
95 const CategoryFilter& category_filter, | 93 const TraceConfig& trace_config, |
96 int mode, | 94 int mode, |
97 const TraceOptions& trace_options, | |
98 const base::Closure& callback) { | 95 const base::Closure& callback) { |
99 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 96 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
100 | 97 |
101 TraceLog::GetInstance()->SetEnabled( | 98 TraceLog::GetInstance()->SetEnabled( |
102 category_filter, static_cast<TraceLog::Mode>(mode), trace_options); | 99 trace_config, static_cast<TraceLog::Mode>(mode)); |
103 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); | 100 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
104 } | 101 } |
105 | 102 |
106 void TracingControllerImpl::SetDisabledOnFileThread( | 103 void TracingControllerImpl::SetDisabledOnFileThread( |
107 const base::Closure& callback) { | 104 const base::Closure& callback) { |
108 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 105 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
109 | 106 |
110 TraceLog::GetInstance()->SetDisabled(); | 107 TraceLog::GetInstance()->SetDisabled(); |
111 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); | 108 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
112 } | 109 } |
113 | 110 |
114 bool TracingControllerImpl::EnableRecording( | 111 bool TracingControllerImpl::EnableRecording( |
115 const CategoryFilter& category_filter, | 112 const TraceConfig& trace_config, |
116 const TraceOptions& trace_options, | |
117 const EnableRecordingDoneCallback& callback) { | 113 const EnableRecordingDoneCallback& callback) { |
118 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 114 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
119 | 115 |
120 if (!can_enable_recording()) | 116 if (!can_enable_recording()) |
121 return false; | 117 return false; |
122 is_recording_ = true; | 118 is_recording_ = true; |
123 | 119 |
124 #if defined(OS_ANDROID) | 120 #if defined(OS_ANDROID) |
125 if (pending_get_categories_done_callback_.is_null()) | 121 if (pending_get_categories_done_callback_.is_null()) |
126 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 122 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
127 #endif | 123 #endif |
128 | 124 |
129 trace_options_ = trace_options; | 125 if (trace_config.IsSystraceEnabled()) { |
130 | |
131 if (trace_options.enable_systrace) { | |
132 #if defined(OS_CHROMEOS) | 126 #if defined(OS_CHROMEOS) |
133 DCHECK(!is_system_tracing_); | 127 DCHECK(!is_system_tracing_); |
134 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> | 128 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> |
135 StartSystemTracing(); | 129 StartSystemTracing(); |
136 is_system_tracing_ = true; | 130 is_system_tracing_ = true; |
137 #elif defined(OS_WIN) | 131 #elif defined(OS_WIN) |
138 DCHECK(!is_system_tracing_); | 132 DCHECK(!is_system_tracing_); |
139 is_system_tracing_ = | 133 is_system_tracing_ = |
140 EtwSystemEventConsumer::GetInstance()->StartSystemTracing(); | 134 EtwSystemEventConsumer::GetInstance()->StartSystemTracing(); |
141 #endif | 135 #endif |
142 } | 136 } |
143 | 137 |
144 | 138 |
145 base::Closure on_enable_recording_done_callback = | 139 base::Closure on_enable_recording_done_callback = |
146 base::Bind(&TracingControllerImpl::OnEnableRecordingDone, | 140 base::Bind(&TracingControllerImpl::OnEnableRecordingDone, |
147 base::Unretained(this), | 141 base::Unretained(this), |
148 category_filter, trace_options, callback); | 142 trace_config, callback); |
149 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 143 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
150 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, | 144 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
151 base::Unretained(this), | 145 base::Unretained(this), |
152 category_filter, | 146 trace_config, |
153 base::trace_event::TraceLog::RECORDING_MODE, | 147 base::trace_event::TraceLog::RECORDING_MODE, |
154 trace_options, | |
155 on_enable_recording_done_callback)); | 148 on_enable_recording_done_callback)); |
156 return true; | 149 return true; |
157 } | 150 } |
158 | 151 |
159 void TracingControllerImpl::OnEnableRecordingDone( | 152 void TracingControllerImpl::OnEnableRecordingDone( |
160 const CategoryFilter& category_filter, | 153 const TraceConfig& trace_config, |
161 const TraceOptions& trace_options, | |
162 const EnableRecordingDoneCallback& callback) { | 154 const EnableRecordingDoneCallback& callback) { |
163 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 155 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
164 | 156 |
165 // Notify all child processes. | 157 // Notify all child processes. |
166 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 158 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
167 it != trace_message_filters_.end(); ++it) { | 159 it != trace_message_filters_.end(); ++it) { |
168 it->get()->SendBeginTracing(category_filter, trace_options); | 160 it->get()->SendBeginTracing(trace_config); |
169 } | 161 } |
170 | 162 |
171 if (!callback.is_null()) | 163 if (!callback.is_null()) |
172 callback.Run(); | 164 callback.Run(); |
173 } | 165 } |
174 | 166 |
175 bool TracingControllerImpl::DisableRecording( | 167 bool TracingControllerImpl::DisableRecording( |
176 const scoped_refptr<TraceDataSink>& trace_data_sink) { | 168 const scoped_refptr<TraceDataSink>& trace_data_sink) { |
177 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 169 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
178 | 170 |
179 if (!can_disable_recording()) | 171 if (!can_disable_recording()) |
180 return false; | 172 return false; |
181 | 173 |
182 trace_data_sink_ = trace_data_sink; | 174 trace_data_sink_ = trace_data_sink; |
183 trace_options_ = TraceOptions(); | |
184 // Disable local trace early to avoid traces during end-tracing process from | 175 // Disable local trace early to avoid traces during end-tracing process from |
185 // interfering with the process. | 176 // interfering with the process. |
186 base::Closure on_disable_recording_done_callback = base::Bind( | 177 base::Closure on_disable_recording_done_callback = base::Bind( |
187 &TracingControllerImpl::OnDisableRecordingDone, base::Unretained(this)); | 178 &TracingControllerImpl::OnDisableRecordingDone, base::Unretained(this)); |
188 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 179 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
189 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, | 180 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, |
190 base::Unretained(this), | 181 base::Unretained(this), |
191 on_disable_recording_done_callback)); | 182 on_disable_recording_done_callback)); |
192 return true; | 183 return true; |
193 } | 184 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 } | 231 } |
241 | 232 |
242 // Notify all child processes. | 233 // Notify all child processes. |
243 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 234 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
244 it != trace_message_filters_.end(); ++it) { | 235 it != trace_message_filters_.end(); ++it) { |
245 it->get()->SendEndTracing(); | 236 it->get()->SendEndTracing(); |
246 } | 237 } |
247 } | 238 } |
248 | 239 |
249 bool TracingControllerImpl::EnableMonitoring( | 240 bool TracingControllerImpl::EnableMonitoring( |
250 const CategoryFilter& category_filter, | 241 const TraceConfig& trace_config, |
251 const TraceOptions& trace_options, | |
252 const EnableMonitoringDoneCallback& callback) { | 242 const EnableMonitoringDoneCallback& callback) { |
253 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 243 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
254 | 244 |
255 if (!can_enable_monitoring()) | 245 if (!can_enable_monitoring()) |
256 return false; | 246 return false; |
257 OnMonitoringStateChanged(true); | 247 OnMonitoringStateChanged(true); |
258 | 248 |
259 #if defined(OS_ANDROID) | 249 #if defined(OS_ANDROID) |
260 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); | 250 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); |
261 #endif | 251 #endif |
262 | 252 |
263 trace_options_ = trace_options; | |
264 | |
265 base::Closure on_enable_monitoring_done_callback = | 253 base::Closure on_enable_monitoring_done_callback = |
266 base::Bind(&TracingControllerImpl::OnEnableMonitoringDone, | 254 base::Bind(&TracingControllerImpl::OnEnableMonitoringDone, |
267 base::Unretained(this), | 255 base::Unretained(this), |
268 category_filter, trace_options, callback); | 256 trace_config, callback); |
269 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 257 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
270 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, | 258 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
271 base::Unretained(this), | 259 base::Unretained(this), |
272 category_filter, | 260 trace_config, |
273 base::trace_event::TraceLog::MONITORING_MODE, | 261 base::trace_event::TraceLog::MONITORING_MODE, |
274 trace_options, | |
275 on_enable_monitoring_done_callback)); | 262 on_enable_monitoring_done_callback)); |
276 return true; | 263 return true; |
277 } | 264 } |
278 | 265 |
279 void TracingControllerImpl::OnEnableMonitoringDone( | 266 void TracingControllerImpl::OnEnableMonitoringDone( |
280 const CategoryFilter& category_filter, | 267 const TraceConfig& trace_config, |
281 const TraceOptions& trace_options, | |
282 const EnableMonitoringDoneCallback& callback) { | 268 const EnableMonitoringDoneCallback& callback) { |
283 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 269 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
284 | 270 |
285 // Notify all child processes. | 271 // Notify all child processes. |
286 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 272 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
287 it != trace_message_filters_.end(); ++it) { | 273 it != trace_message_filters_.end(); ++it) { |
288 it->get()->SendEnableMonitoring(category_filter, trace_options); | 274 it->get()->SendEnableMonitoring(trace_config); |
289 } | 275 } |
290 | 276 |
291 if (!callback.is_null()) | 277 if (!callback.is_null()) |
292 callback.Run(); | 278 callback.Run(); |
293 } | 279 } |
294 | 280 |
295 bool TracingControllerImpl::DisableMonitoring( | 281 bool TracingControllerImpl::DisableMonitoring( |
296 const DisableMonitoringDoneCallback& callback) { | 282 const DisableMonitoringDoneCallback& callback) { |
297 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 283 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
298 | 284 |
299 if (!can_disable_monitoring()) | 285 if (!can_disable_monitoring()) |
300 return false; | 286 return false; |
301 | 287 |
302 trace_options_ = TraceOptions(); | |
303 base::Closure on_disable_monitoring_done_callback = | 288 base::Closure on_disable_monitoring_done_callback = |
304 base::Bind(&TracingControllerImpl::OnDisableMonitoringDone, | 289 base::Bind(&TracingControllerImpl::OnDisableMonitoringDone, |
305 base::Unretained(this), callback); | 290 base::Unretained(this), callback); |
306 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 291 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
307 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, | 292 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, |
308 base::Unretained(this), | 293 base::Unretained(this), |
309 on_disable_monitoring_done_callback)); | 294 on_disable_monitoring_done_callback)); |
310 return true; | 295 return true; |
311 } | 296 } |
312 | 297 |
313 void TracingControllerImpl::OnDisableMonitoringDone( | 298 void TracingControllerImpl::OnDisableMonitoringDone( |
314 const DisableMonitoringDoneCallback& callback) { | 299 const DisableMonitoringDoneCallback& callback) { |
315 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 300 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
316 | 301 |
317 OnMonitoringStateChanged(false); | 302 OnMonitoringStateChanged(false); |
318 | 303 |
319 // Notify all child processes. | 304 // Notify all child processes. |
320 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 305 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
321 it != trace_message_filters_.end(); ++it) { | 306 it != trace_message_filters_.end(); ++it) { |
322 it->get()->SendDisableMonitoring(); | 307 it->get()->SendDisableMonitoring(); |
323 } | 308 } |
324 if (!callback.is_null()) | 309 if (!callback.is_null()) |
325 callback.Run(); | 310 callback.Run(); |
326 } | 311 } |
327 | 312 |
328 void TracingControllerImpl::GetMonitoringStatus( | 313 void TracingControllerImpl::GetMonitoringStatus( |
329 bool* out_enabled, | 314 bool* out_enabled, |
330 CategoryFilter* out_category_filter, | 315 TraceConfig* out_trace_config) { |
331 TraceOptions* out_trace_options) { | |
332 *out_enabled = is_monitoring_; | 316 *out_enabled = is_monitoring_; |
333 *out_category_filter = TraceLog::GetInstance()->GetCurrentCategoryFilter(); | 317 *out_trace_config = TraceLog::GetInstance()->GetCurrentTraceConfig(); |
334 *out_trace_options = trace_options_; | |
335 } | 318 } |
336 | 319 |
337 bool TracingControllerImpl::CaptureMonitoringSnapshot( | 320 bool TracingControllerImpl::CaptureMonitoringSnapshot( |
338 const scoped_refptr<TraceDataSink>& monitoring_data_sink) { | 321 const scoped_refptr<TraceDataSink>& monitoring_data_sink) { |
339 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 322 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
340 | 323 |
341 if (!can_disable_monitoring()) | 324 if (!can_disable_monitoring()) |
342 return false; | 325 return false; |
343 | 326 |
344 if (!monitoring_data_sink.get()) | 327 if (!monitoring_data_sink.get()) |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 return; | 442 return; |
460 } | 443 } |
461 | 444 |
462 trace_message_filters_.insert(trace_message_filter); | 445 trace_message_filters_.insert(trace_message_filter); |
463 if (can_cancel_watch_event()) { | 446 if (can_cancel_watch_event()) { |
464 trace_message_filter->SendSetWatchEvent(watch_category_name_, | 447 trace_message_filter->SendSetWatchEvent(watch_category_name_, |
465 watch_event_name_); | 448 watch_event_name_); |
466 } | 449 } |
467 if (can_disable_recording()) { | 450 if (can_disable_recording()) { |
468 trace_message_filter->SendBeginTracing( | 451 trace_message_filter->SendBeginTracing( |
469 TraceLog::GetInstance()->GetCurrentCategoryFilter(), | 452 TraceLog::GetInstance()->GetCurrentTraceConfig()); |
470 TraceLog::GetInstance()->GetCurrentTraceOptions()); | |
471 } | 453 } |
472 if (can_disable_monitoring()) { | 454 if (can_disable_monitoring()) { |
473 trace_message_filter->SendEnableMonitoring( | 455 trace_message_filter->SendEnableMonitoring( |
474 TraceLog::GetInstance()->GetCurrentCategoryFilter(), | 456 TraceLog::GetInstance()->GetCurrentTraceConfig()); |
475 TraceLog::GetInstance()->GetCurrentTraceOptions()); | |
476 } | 457 } |
477 } | 458 } |
478 | 459 |
479 void TracingControllerImpl::RemoveTraceMessageFilter( | 460 void TracingControllerImpl::RemoveTraceMessageFilter( |
480 TraceMessageFilter* trace_message_filter) { | 461 TraceMessageFilter* trace_message_filter) { |
481 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 462 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
482 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 463 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
483 base::Bind(&TracingControllerImpl::RemoveTraceMessageFilter, | 464 base::Bind(&TracingControllerImpl::RemoveTraceMessageFilter, |
484 base::Unretained(this), | 465 base::Unretained(this), |
485 make_scoped_refptr(trace_message_filter))); | 466 make_scoped_refptr(trace_message_filter))); |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 is_monitoring_ = is_monitoring; | 855 is_monitoring_ = is_monitoring; |
875 #if !defined(OS_ANDROID) | 856 #if !defined(OS_ANDROID) |
876 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); | 857 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); |
877 it != tracing_uis_.end(); it++) { | 858 it != tracing_uis_.end(); it++) { |
878 (*it)->OnMonitoringStateChanged(is_monitoring); | 859 (*it)->OnMonitoringStateChanged(is_monitoring); |
879 } | 860 } |
880 #endif | 861 #endif |
881 } | 862 } |
882 | 863 |
883 } // namespace content | 864 } // namespace content |
OLD | NEW |