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

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

Issue 171143002: Implements Windows system tracing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tracing
Patch Set: nits Created 6 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 4
5 #include "content/browser/tracing/tracing_controller_impl.h" 5 #include "content/browser/tracing/tracing_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/json/string_escape.h" 10 #include "base/json/string_escape.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "content/browser/tracing/trace_message_filter.h" 12 #include "content/browser/tracing/trace_message_filter.h"
13 #include "content/browser/tracing/tracing_ui.h" 13 #include "content/browser/tracing/tracing_ui.h"
14 #include "content/common/child_process_messages.h" 14 #include "content/common/child_process_messages.h"
15 #include "content/public/browser/browser_message_filter.h" 15 #include "content/public/browser/browser_message_filter.h"
16 #include "content/public/common/content_switches.h" 16 #include "content/public/common/content_switches.h"
17 17
18 #if defined(OS_CHROMEOS) 18 #if defined(OS_CHROMEOS)
19 #include "chromeos/dbus/dbus_thread_manager.h" 19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/debug_daemon_client.h" 20 #include "chromeos/dbus/debug_daemon_client.h"
21 #endif 21 #endif
22 22
23 #if defined(OS_WIN)
24 #include "content/browser/tracing/etw_system_event_consumer_win.h"
25 #endif
26
23 using base::debug::TraceLog; 27 using base::debug::TraceLog;
24 28
25 namespace content { 29 namespace content {
26 30
27 namespace { 31 namespace {
28 32
29 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = 33 base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
30 LAZY_INSTANCE_INITIALIZER; 34 LAZY_INSTANCE_INITIALIZER;
31 35
32 } // namespace 36 } // namespace
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 const char* preamble = "{\"traceEvents\": ["; 98 const char* preamble = "{\"traceEvents\": [";
95 size_t written = fwrite(preamble, strlen(preamble), 1, file_); 99 size_t written = fwrite(preamble, strlen(preamble), 1, file_);
96 DCHECK(written == 1); 100 DCHECK(written == 1);
97 } 101 }
98 102
99 void TracingControllerImpl::ResultFile::WriteTask( 103 void TracingControllerImpl::ResultFile::WriteTask(
100 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 104 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
101 if (!file_ || !events_str_ptr->data().size()) 105 if (!file_ || !events_str_ptr->data().size())
102 return; 106 return;
103 107
104 // If there is already a result in the file, then put a commma 108 // If there is already a result in the file, then put a comma
105 // before the next batch of results. 109 // before the next batch of results.
106 if (has_at_least_one_result_) { 110 if (has_at_least_one_result_) {
107 size_t written = fwrite(",", 1, 1, file_); 111 size_t written = fwrite(",", 1, 1, file_);
108 DCHECK(written == 1); 112 DCHECK(written == 1);
109 } 113 }
110 has_at_least_one_result_ = true; 114 has_at_least_one_result_ = true;
111 size_t written = fwrite(events_str_ptr->data().c_str(), 115 size_t written = fwrite(events_str_ptr->data().c_str(),
112 events_str_ptr->data().size(), 1, 116 events_str_ptr->data().size(), 1,
113 file_); 117 file_);
114 DCHECK(written == 1); 118 DCHECK(written == 1);
115 } 119 }
116 120
117 void TracingControllerImpl::ResultFile::WriteSystemTraceTask( 121 void TracingControllerImpl::ResultFile::WriteSystemTraceTask(
118 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 122 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
119 system_trace_ = events_str_ptr; 123 system_trace_ = events_str_ptr;
120 } 124 }
121 125
122 void TracingControllerImpl::ResultFile::CloseTask( 126 void TracingControllerImpl::ResultFile::CloseTask(
123 const base::Closure& callback) { 127 const base::Closure& callback) {
124 if (!file_) 128 if (!file_)
125 return; 129 return;
126 130
127 const char* trailevents = "]"; 131 const char* trailevents = "]";
128 size_t written = fwrite(trailevents, strlen(trailevents), 1, file_); 132 size_t written = fwrite(trailevents, strlen(trailevents), 1, file_);
129 DCHECK(written == 1); 133 DCHECK(written == 1);
130 134
131 if (system_trace_) { 135 if (system_trace_) {
136 #if defined(OS_WIN)
137 // The Windows kernel events are kept into a JSon format stored as string
138 // and must no be escaped.
139 std::string json_string = system_trace_->data();
140 #else
132 std::string json_string = base::GetQuotedJSONString(system_trace_->data()); 141 std::string json_string = base::GetQuotedJSONString(system_trace_->data());
142 #endif
133 143
134 const char* systemTraceHead = ", \"systemTraceEvents\": "; 144 const char* systemTraceHead = ",\n\"systemTraceEvents\": ";
135 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_); 145 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_);
136 DCHECK(written == 1); 146 DCHECK(written == 1);
137 147
138 written = fwrite(json_string.data(), json_string.size(), 1, file_); 148 written = fwrite(json_string.data(), json_string.size(), 1, file_);
139 DCHECK(written == 1); 149 DCHECK(written == 1);
140 150
141 system_trace_ = NULL; 151 system_trace_ = NULL;
142 } 152 }
143 153
144 const char* trailout = "}"; 154 const char* trailout = "}";
145 written = fwrite(trailout, strlen(trailout), 1, file_); 155 written = fwrite(trailout, strlen(trailout), 1, file_);
146 DCHECK(written == 1); 156 DCHECK(written == 1);
147 base::CloseFile(file_); 157 base::CloseFile(file_);
148 file_ = NULL; 158 file_ = NULL;
149 159
150 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); 160 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
151 } 161 }
152 162
153 163
154 TracingControllerImpl::TracingControllerImpl() : 164 TracingControllerImpl::TracingControllerImpl() :
155 pending_disable_recording_ack_count_(0), 165 pending_disable_recording_ack_count_(0),
156 pending_capture_monitoring_snapshot_ack_count_(0), 166 pending_capture_monitoring_snapshot_ack_count_(0),
157 pending_trace_buffer_percent_full_ack_count_(0), 167 pending_trace_buffer_percent_full_ack_count_(0),
158 maximum_trace_buffer_percent_full_(0), 168 maximum_trace_buffer_percent_full_(0),
159 // Tracing may have been enabled by ContentMainRunner if kTraceStartup 169 // Tracing may have been enabled by ContentMainRunner if kTraceStartup
160 // is specified in command line. 170 // is specified in command line.
161 #if defined(OS_CHROMEOS) 171 #if defined(OS_CHROMEOS) || defined(OS_WIN)
162 is_system_tracing_(false), 172 is_system_tracing_(false),
163 #endif 173 #endif
164 is_recording_(TraceLog::GetInstance()->IsEnabled()), 174 is_recording_(TraceLog::GetInstance()->IsEnabled()),
165 is_monitoring_(false) { 175 is_monitoring_(false) {
166 } 176 }
167 177
168 TracingControllerImpl::~TracingControllerImpl() { 178 TracingControllerImpl::~TracingControllerImpl() {
169 // This is a Leaky instance. 179 // This is a Leaky instance.
170 NOTREACHED(); 180 NOTREACHED();
171 } 181 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 237
228 #if defined(OS_ANDROID) 238 #if defined(OS_ANDROID)
229 if (pending_get_categories_done_callback_.is_null()) 239 if (pending_get_categories_done_callback_.is_null())
230 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); 240 TraceLog::GetInstance()->AddClockSyncMetadataEvent();
231 #endif 241 #endif
232 242
233 options_ = options; 243 options_ = options;
234 int trace_options = (options & RECORD_CONTINUOUSLY) ? 244 int trace_options = (options & RECORD_CONTINUOUSLY) ?
235 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; 245 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL;
236 if (options & ENABLE_SAMPLING) { 246 if (options & ENABLE_SAMPLING) {
237 trace_options |= TraceLog::ENABLE_SAMPLING; 247 trace_options |= TraceLog::ENABLE_SAMPLING;
238 } 248 }
239 #if defined(OS_CHROMEOS) 249
240 if (options & ENABLE_SYSTRACE) { 250 if (options & ENABLE_SYSTRACE) {
241 DCHECK(!is_system_tracing_); 251 DCHECK(!is_system_tracing_);
252 #if defined(OS_CHROMEOS)
242 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> 253 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
243 StartSystemTracing(); 254 StartSystemTracing();
244 is_system_tracing_ = true; 255 is_system_tracing_ = true;
256 #elif defined(OS_WIN)
257 is_system_tracing_ =
258 EtwSystemEventConsumer::GetInstance()->StartSystemTracing();
259 #endif
245 } 260 }
246 #endif 261
247 262
248 base::Closure on_enable_recording_done_callback = 263 base::Closure on_enable_recording_done_callback =
249 base::Bind(&TracingControllerImpl::OnEnableRecordingDone, 264 base::Bind(&TracingControllerImpl::OnEnableRecordingDone,
250 base::Unretained(this), 265 base::Unretained(this),
251 category_filter,trace_options, callback); 266 category_filter, trace_options, callback);
252 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 267 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
253 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, 268 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
254 base::Unretained(this), 269 base::Unretained(this),
255 category_filter, 270 category_filter,
256 base::debug::TraceLog::RECORDING_MODE, 271 base::debug::TraceLog::RECORDING_MODE,
257 trace_options, 272 trace_options,
258 on_enable_recording_done_callback)); 273 on_enable_recording_done_callback));
259 return true; 274 return true;
260 } 275 }
261 276
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 if (!callback.is_null()) 433 if (!callback.is_null())
419 callback.Run(); 434 callback.Run();
420 } 435 }
421 436
422 void TracingControllerImpl::GetMonitoringStatus( 437 void TracingControllerImpl::GetMonitoringStatus(
423 bool* out_enabled, 438 bool* out_enabled,
424 std::string* out_category_filter, 439 std::string* out_category_filter,
425 TracingController::Options* out_options) { 440 TracingController::Options* out_options) {
426 *out_enabled = is_monitoring_; 441 *out_enabled = is_monitoring_;
427 *out_category_filter = 442 *out_category_filter =
428 TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString(); 443 TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString();
429 *out_options = options_; 444 *out_options = options_;
430 } 445 }
431 446
432 bool TracingControllerImpl::CaptureMonitoringSnapshot( 447 bool TracingControllerImpl::CaptureMonitoringSnapshot(
433 const base::FilePath& result_file_path, 448 const base::FilePath& result_file_path,
434 const TracingFileResultCallback& callback) { 449 const TracingFileResultCallback& callback) {
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 450 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
436 451
437 if (!can_disable_monitoring()) 452 if (!can_disable_monitoring())
438 return false; 453 return false;
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 return; 674 return;
660 675
661 OnDisableRecordingComplete(); 676 OnDisableRecordingComplete();
662 } 677 }
663 678
664 void TracingControllerImpl::OnDisableRecordingComplete() { 679 void TracingControllerImpl::OnDisableRecordingComplete() {
665 // All acks (including from the subprocesses and the local trace) have been 680 // All acks (including from the subprocesses and the local trace) have been
666 // received. 681 // received.
667 is_recording_ = false; 682 is_recording_ = false;
668 683
684 if (is_system_tracing_) {
685 // Disable system tracing.
686 is_system_tracing_ = false;
687
669 #if defined(OS_CHROMEOS) 688 #if defined(OS_CHROMEOS)
670 if (is_system_tracing_) {
671 // Disable system tracing now that the local trace has shutdown. 689 // Disable system tracing now that the local trace has shutdown.
672 // This must be done last because we potentially need to push event 690 // This must be done last because we potentially need to push event
673 // records into the system event log for synchronizing system event 691 // records into the system event log for synchronizing system event
674 // timestamps with chrome event timestamps--and since the system event 692 // timestamps with chrome event timestamps--and since the system event
675 // log is a ring-buffer (on linux) adding them at the end is the only 693 // log is a ring-buffer (on linux) adding them at the end is the only
676 // way we're confident we'll have them in the final result. 694 // way we're confident we'll have them in the final result.
677 is_system_tracing_ = false;
678 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> 695 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
679 RequestStopSystemTracing( 696 RequestStopSystemTracing(
680 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked, 697 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
681 base::Unretained(this))); 698 base::Unretained(this)));
699 #elif defined(OS_WIN)
700 // Stop kernel tracing and flush events.
701 EtwSystemEventConsumer::GetInstance()->StopSystemTracing(
702 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
703 base::Unretained(this)));
704 #endif
682 return; 705 return;
683 } 706 }
684 #endif
685 707
686 // Trigger callback if one is set. 708 // Trigger callback if one is set.
687 if (!pending_get_categories_done_callback_.is_null()) { 709 if (!pending_get_categories_done_callback_.is_null()) {
688 pending_get_categories_done_callback_.Run(known_category_groups_); 710 pending_get_categories_done_callback_.Run(known_category_groups_);
689 pending_get_categories_done_callback_.Reset(); 711 pending_get_categories_done_callback_.Reset();
690 } else if (result_file_) { 712 } else if (result_file_) {
691 result_file_->Close( 713 result_file_->Close(
692 base::Bind(&TracingControllerImpl::OnResultFileClosed, 714 base::Bind(&TracingControllerImpl::OnResultFileClosed,
693 base::Unretained(this))); 715 base::Unretained(this)));
694 } 716 }
695 } 717 }
696 718
697 void TracingControllerImpl::OnResultFileClosed() { 719 void TracingControllerImpl::OnResultFileClosed() {
698 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 720 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
699 721
700 if (!result_file_) 722 if (!result_file_)
701 return; 723 return;
702 724
703 if (!pending_disable_recording_done_callback_.is_null()) { 725 if (!pending_disable_recording_done_callback_.is_null()) {
704 pending_disable_recording_done_callback_.Run(result_file_->path()); 726 pending_disable_recording_done_callback_.Run(result_file_->path());
705 pending_disable_recording_done_callback_.Reset(); 727 pending_disable_recording_done_callback_.Reset();
706 } 728 }
707 result_file_.reset(); 729 result_file_.reset();
708 } 730 }
709 731
710 #if defined(OS_CHROMEOS) 732 #if defined(OS_CHROMEOS) || defined(OS_WIN)
711 void TracingControllerImpl::OnEndSystemTracingAcked( 733 void TracingControllerImpl::OnEndSystemTracingAcked(
712 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 734 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
713 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
714 736
715 if (result_file_) 737 if (result_file_)
716 result_file_->WriteSystemTrace(events_str_ptr); 738 result_file_->WriteSystemTrace(events_str_ptr);
717 739
718 DCHECK(!is_system_tracing_); 740 DCHECK(!is_system_tracing_);
719 OnDisableRecordingComplete(); 741 OnDisableRecordingComplete();
720 } 742 }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 888 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
867 base::Bind(&TracingControllerImpl::OnWatchEventMatched, 889 base::Bind(&TracingControllerImpl::OnWatchEventMatched,
868 base::Unretained(this))); 890 base::Unretained(this)));
869 return; 891 return;
870 } 892 }
871 893
872 if (!watch_event_callback_.is_null()) 894 if (!watch_event_callback_.is_null())
873 watch_event_callback_.Run(); 895 watch_event_callback_.Run();
874 } 896 }
875 897
876 void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) 898 void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) {
877 {
878 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end()); 899 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end());
879 tracing_uis_.insert(tracing_ui); 900 tracing_uis_.insert(tracing_ui);
880 } 901 }
881 902
882 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) 903 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
883 {
884 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui); 904 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui);
885 DCHECK(it != tracing_uis_.end()); 905 DCHECK(it != tracing_uis_.end());
886 tracing_uis_.erase(it); 906 tracing_uis_.erase(it);
887 } 907 }
888 908
889 void TracingControllerImpl::OnMonitoringStateChanged(bool is_monitoring) 909 void TracingControllerImpl::OnMonitoringStateChanged(bool is_monitoring) {
890 {
891 if (is_monitoring_ == is_monitoring) 910 if (is_monitoring_ == is_monitoring)
892 return; 911 return;
893 912
894 is_monitoring_ = is_monitoring; 913 is_monitoring_ = is_monitoring;
895 #if !defined(OS_ANDROID) 914 #if !defined(OS_ANDROID)
896 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); 915 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin();
897 it != tracing_uis_.end(); it++) { 916 it != tracing_uis_.end(); it++) {
898 (*it)->OnMonitoringStateChanged(is_monitoring); 917 (*it)->OnMonitoringStateChanged(is_monitoring);
899 } 918 }
900 #endif 919 #endif
901 } 920 }
902 921
903 } // namespace content 922 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698