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

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: fix android build Created 6 years, 9 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') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
5 #include "content/browser/tracing/tracing_controller_impl.h" 4 #include "content/browser/tracing/tracing_controller_impl.h"
6 5
7 #include "base/bind.h" 6 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
9 #include "base/file_util.h" 8 #include "base/file_util.h"
10 #include "base/json/string_escape.h" 9 #include "base/json/string_escape.h"
11 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
12 #include "content/browser/tracing/trace_message_filter.h" 11 #include "content/browser/tracing/trace_message_filter.h"
13 #include "content/browser/tracing/tracing_ui.h" 12 #include "content/browser/tracing/tracing_ui.h"
14 #include "content/common/child_process_messages.h" 13 #include "content/common/child_process_messages.h"
15 #include "content/public/browser/browser_message_filter.h" 14 #include "content/public/browser/browser_message_filter.h"
16 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
17 16
18 #if defined(OS_CHROMEOS) 17 #if defined(OS_CHROMEOS)
19 #include "chromeos/dbus/dbus_thread_manager.h" 18 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/debug_daemon_client.h" 19 #include "chromeos/dbus/debug_daemon_client.h"
21 #endif 20 #endif
22 21
22 #if defined(OS_WIN)
23 #include "content/browser/tracing/etw_system_event_consumer_win.h"
24 #endif
25
23 using base::debug::TraceLog; 26 using base::debug::TraceLog;
24 27
25 namespace content { 28 namespace content {
26 29
27 namespace { 30 namespace {
28 31
29 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = 32 base::LazyInstance<TracingControllerImpl>::Leaky g_controller =
30 LAZY_INSTANCE_INITIALIZER; 33 LAZY_INSTANCE_INITIALIZER;
31 34
32 } // namespace 35 } // namespace
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 const char* preamble = "{\"traceEvents\": ["; 97 const char* preamble = "{\"traceEvents\": [";
95 size_t written = fwrite(preamble, strlen(preamble), 1, file_); 98 size_t written = fwrite(preamble, strlen(preamble), 1, file_);
96 DCHECK(written == 1); 99 DCHECK(written == 1);
97 } 100 }
98 101
99 void TracingControllerImpl::ResultFile::WriteTask( 102 void TracingControllerImpl::ResultFile::WriteTask(
100 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 103 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
101 if (!file_ || !events_str_ptr->data().size()) 104 if (!file_ || !events_str_ptr->data().size())
102 return; 105 return;
103 106
104 // If there is already a result in the file, then put a commma 107 // If there is already a result in the file, then put a comma
105 // before the next batch of results. 108 // before the next batch of results.
106 if (has_at_least_one_result_) { 109 if (has_at_least_one_result_) {
107 size_t written = fwrite(",", 1, 1, file_); 110 size_t written = fwrite(",", 1, 1, file_);
108 DCHECK(written == 1); 111 DCHECK(written == 1);
109 } 112 }
110 has_at_least_one_result_ = true; 113 has_at_least_one_result_ = true;
111 size_t written = fwrite(events_str_ptr->data().c_str(), 114 size_t written = fwrite(events_str_ptr->data().c_str(),
112 events_str_ptr->data().size(), 1, 115 events_str_ptr->data().size(), 1,
113 file_); 116 file_);
114 DCHECK(written == 1); 117 DCHECK(written == 1);
115 } 118 }
116 119
117 void TracingControllerImpl::ResultFile::WriteSystemTraceTask( 120 void TracingControllerImpl::ResultFile::WriteSystemTraceTask(
118 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 121 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
119 system_trace_ = events_str_ptr; 122 system_trace_ = events_str_ptr;
120 } 123 }
121 124
122 void TracingControllerImpl::ResultFile::CloseTask( 125 void TracingControllerImpl::ResultFile::CloseTask(
123 const base::Closure& callback) { 126 const base::Closure& callback) {
124 if (!file_) 127 if (!file_)
125 return; 128 return;
126 129
127 const char* trailevents = "]"; 130 const char* trailevents = "]";
128 size_t written = fwrite(trailevents, strlen(trailevents), 1, file_); 131 size_t written = fwrite(trailevents, strlen(trailevents), 1, file_);
129 DCHECK(written == 1); 132 DCHECK(written == 1);
130 133
131 if (system_trace_) { 134 if (system_trace_) {
135 #if defined(OS_WIN)
136 // The Windows kernel events are kept into a JSon format stored as string
137 // and must not be escaped.
138 std::string json_string = system_trace_->data();
139 #else
132 std::string json_string = base::GetQuotedJSONString(system_trace_->data()); 140 std::string json_string = base::GetQuotedJSONString(system_trace_->data());
141 #endif
133 142
134 const char* systemTraceHead = ", \"systemTraceEvents\": "; 143 const char* systemTraceHead = ",\n\"systemTraceEvents\": ";
135 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_); 144 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_);
136 DCHECK(written == 1); 145 DCHECK(written == 1);
137 146
138 written = fwrite(json_string.data(), json_string.size(), 1, file_); 147 written = fwrite(json_string.data(), json_string.size(), 1, file_);
139 DCHECK(written == 1); 148 DCHECK(written == 1);
140 149
141 system_trace_ = NULL; 150 system_trace_ = NULL;
142 } 151 }
143 152
144 const char* trailout = "}"; 153 const char* trailout = "}";
145 written = fwrite(trailout, strlen(trailout), 1, file_); 154 written = fwrite(trailout, strlen(trailout), 1, file_);
146 DCHECK(written == 1); 155 DCHECK(written == 1);
147 base::CloseFile(file_); 156 base::CloseFile(file_);
148 file_ = NULL; 157 file_ = NULL;
149 158
150 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); 159 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
151 } 160 }
152 161
153 162
154 TracingControllerImpl::TracingControllerImpl() : 163 TracingControllerImpl::TracingControllerImpl() :
155 pending_disable_recording_ack_count_(0), 164 pending_disable_recording_ack_count_(0),
156 pending_capture_monitoring_snapshot_ack_count_(0), 165 pending_capture_monitoring_snapshot_ack_count_(0),
157 pending_trace_buffer_percent_full_ack_count_(0), 166 pending_trace_buffer_percent_full_ack_count_(0),
158 maximum_trace_buffer_percent_full_(0), 167 maximum_trace_buffer_percent_full_(0),
159 // Tracing may have been enabled by ContentMainRunner if kTraceStartup 168 // Tracing may have been enabled by ContentMainRunner if kTraceStartup
160 // is specified in command line. 169 // is specified in command line.
161 #if defined(OS_CHROMEOS) 170 #if defined(OS_CHROMEOS) || defined(OS_WIN)
162 is_system_tracing_(false), 171 is_system_tracing_(false),
163 #endif 172 #endif
164 is_recording_(TraceLog::GetInstance()->IsEnabled()), 173 is_recording_(TraceLog::GetInstance()->IsEnabled()),
165 is_monitoring_(false) { 174 is_monitoring_(false) {
166 } 175 }
167 176
168 TracingControllerImpl::~TracingControllerImpl() { 177 TracingControllerImpl::~TracingControllerImpl() {
169 // This is a Leaky instance. 178 // This is a Leaky instance.
170 NOTREACHED(); 179 NOTREACHED();
171 } 180 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 236
228 #if defined(OS_ANDROID) 237 #if defined(OS_ANDROID)
229 if (pending_get_categories_done_callback_.is_null()) 238 if (pending_get_categories_done_callback_.is_null())
230 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); 239 TraceLog::GetInstance()->AddClockSyncMetadataEvent();
231 #endif 240 #endif
232 241
233 options_ = options; 242 options_ = options;
234 int trace_options = (options & RECORD_CONTINUOUSLY) ? 243 int trace_options = (options & RECORD_CONTINUOUSLY) ?
235 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; 244 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL;
236 if (options & ENABLE_SAMPLING) { 245 if (options & ENABLE_SAMPLING) {
237 trace_options |= TraceLog::ENABLE_SAMPLING; 246 trace_options |= TraceLog::ENABLE_SAMPLING;
238 } 247 }
248
249 if (options & ENABLE_SYSTRACE) {
239 #if defined(OS_CHROMEOS) 250 #if defined(OS_CHROMEOS)
240 if (options & ENABLE_SYSTRACE) {
241 DCHECK(!is_system_tracing_); 251 DCHECK(!is_system_tracing_);
242 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> 252 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
243 StartSystemTracing(); 253 StartSystemTracing();
244 is_system_tracing_ = true; 254 is_system_tracing_ = true;
255 #elif defined(OS_WIN)
256 DCHECK(!is_system_tracing_);
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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
669 #if defined(OS_CHROMEOS) 684 #if defined(OS_CHROMEOS)
670 if (is_system_tracing_) { 685 if (is_system_tracing_) {
686 // Disable system tracing.
687 is_system_tracing_ = false;
688
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)));
682 return; 699 return;
683 } 700 }
701 #elif defined(OS_WIN)
702 if (is_system_tracing_) {
703 // Disable system tracing.
704 is_system_tracing_ = false;
705
706
707 // Stop kernel tracing and flush events.
708 EtwSystemEventConsumer::GetInstance()->StopSystemTracing(
709 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
710 base::Unretained(this)));
711 return;
712 }
684 #endif 713 #endif
685 714
686 // Trigger callback if one is set. 715 // Trigger callback if one is set.
687 if (!pending_get_categories_done_callback_.is_null()) { 716 if (!pending_get_categories_done_callback_.is_null()) {
688 pending_get_categories_done_callback_.Run(known_category_groups_); 717 pending_get_categories_done_callback_.Run(known_category_groups_);
689 pending_get_categories_done_callback_.Reset(); 718 pending_get_categories_done_callback_.Reset();
690 } else if (result_file_) { 719 } else if (result_file_) {
691 result_file_->Close( 720 result_file_->Close(
692 base::Bind(&TracingControllerImpl::OnResultFileClosed, 721 base::Bind(&TracingControllerImpl::OnResultFileClosed,
693 base::Unretained(this))); 722 base::Unretained(this)));
694 } 723 }
695 } 724 }
696 725
697 void TracingControllerImpl::OnResultFileClosed() { 726 void TracingControllerImpl::OnResultFileClosed() {
698 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 727 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
699 728
700 if (!result_file_) 729 if (!result_file_)
701 return; 730 return;
702 731
703 if (!pending_disable_recording_done_callback_.is_null()) { 732 if (!pending_disable_recording_done_callback_.is_null()) {
704 pending_disable_recording_done_callback_.Run(result_file_->path()); 733 pending_disable_recording_done_callback_.Run(result_file_->path());
705 pending_disable_recording_done_callback_.Reset(); 734 pending_disable_recording_done_callback_.Reset();
706 } 735 }
707 result_file_.reset(); 736 result_file_.reset();
708 } 737 }
709 738
710 #if defined(OS_CHROMEOS) 739 #if defined(OS_CHROMEOS) || defined(OS_WIN)
711 void TracingControllerImpl::OnEndSystemTracingAcked( 740 void TracingControllerImpl::OnEndSystemTracingAcked(
712 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 741 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
713 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
714 743
715 if (result_file_) 744 if (result_file_)
716 result_file_->WriteSystemTrace(events_str_ptr); 745 result_file_->WriteSystemTrace(events_str_ptr);
717 746
718 DCHECK(!is_system_tracing_); 747 DCHECK(!is_system_tracing_);
719 OnDisableRecordingComplete(); 748 OnDisableRecordingComplete();
720 } 749 }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 895 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
867 base::Bind(&TracingControllerImpl::OnWatchEventMatched, 896 base::Bind(&TracingControllerImpl::OnWatchEventMatched,
868 base::Unretained(this))); 897 base::Unretained(this)));
869 return; 898 return;
870 } 899 }
871 900
872 if (!watch_event_callback_.is_null()) 901 if (!watch_event_callback_.is_null())
873 watch_event_callback_.Run(); 902 watch_event_callback_.Run();
874 } 903 }
875 904
876 void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) 905 void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) {
877 {
878 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end()); 906 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end());
879 tracing_uis_.insert(tracing_ui); 907 tracing_uis_.insert(tracing_ui);
880 } 908 }
881 909
882 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) 910 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
883 {
884 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui); 911 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui);
885 DCHECK(it != tracing_uis_.end()); 912 DCHECK(it != tracing_uis_.end());
886 tracing_uis_.erase(it); 913 tracing_uis_.erase(it);
887 } 914 }
888 915
889 void TracingControllerImpl::OnMonitoringStateChanged(bool is_monitoring) 916 void TracingControllerImpl::OnMonitoringStateChanged(bool is_monitoring) {
890 {
891 if (is_monitoring_ == is_monitoring) 917 if (is_monitoring_ == is_monitoring)
892 return; 918 return;
893 919
894 is_monitoring_ = is_monitoring; 920 is_monitoring_ = is_monitoring;
895 #if !defined(OS_ANDROID) 921 #if !defined(OS_ANDROID)
896 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); 922 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin();
897 it != tracing_uis_.end(); it++) { 923 it != tracing_uis_.end(); it++) {
898 (*it)->OnMonitoringStateChanged(is_monitoring); 924 (*it)->OnMonitoringStateChanged(is_monitoring);
899 } 925 }
900 #endif 926 #endif
901 } 927 }
902 928
903 } // namespace content 929 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698