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

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: rebase on ToT 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/tracing_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 // TODO(etienneb): This is ugly patch on windows. We should keep Value for
138 // all OS instead of a string to represent system traces. A good idea
139 // could be to wrap other.
140 std::string json_string = system_trace_->data();
141 #else
132 std::string json_string = base::GetQuotedJSONString(system_trace_->data()); 142 std::string json_string = base::GetQuotedJSONString(system_trace_->data());
143 #endif
133 144
134 const char* systemTraceHead = ", \"systemTraceEvents\": "; 145 const char* systemTraceHead = ",\n\"systemTraceEvents\": ";
135 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_); 146 written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_);
136 DCHECK(written == 1); 147 DCHECK(written == 1);
137 148
138 written = fwrite(json_string.data(), json_string.size(), 1, file_); 149 written = fwrite(json_string.data(), json_string.size(), 1, file_);
139 DCHECK(written == 1); 150 DCHECK(written == 1);
140 151
141 system_trace_ = NULL; 152 system_trace_ = NULL;
142 } 153 }
143 154
144 const char* trailout = "}"; 155 const char* trailout = "}";
145 written = fwrite(trailout, strlen(trailout), 1, file_); 156 written = fwrite(trailout, strlen(trailout), 1, file_);
146 DCHECK(written == 1); 157 DCHECK(written == 1);
147 base::CloseFile(file_); 158 base::CloseFile(file_);
148 file_ = NULL; 159 file_ = NULL;
149 160
150 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); 161 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
151 } 162 }
152 163
153 164
154 TracingControllerImpl::TracingControllerImpl() : 165 TracingControllerImpl::TracingControllerImpl() :
155 pending_disable_recording_ack_count_(0), 166 pending_disable_recording_ack_count_(0),
156 pending_capture_monitoring_snapshot_ack_count_(0), 167 pending_capture_monitoring_snapshot_ack_count_(0),
157 pending_trace_buffer_percent_full_ack_count_(0), 168 pending_trace_buffer_percent_full_ack_count_(0),
158 maximum_trace_buffer_percent_full_(0), 169 maximum_trace_buffer_percent_full_(0),
159 // Tracing may have been enabled by ContentMainRunner if kTraceStartup 170 // Tracing may have been enabled by ContentMainRunner if kTraceStartup
160 // is specified in command line. 171 // is specified in command line.
161 #if defined(OS_CHROMEOS) 172 #if defined(OS_CHROMEOS) || defined(OS_WIN)
162 is_system_tracing_(false), 173 is_system_tracing_(false),
163 #endif 174 #endif
164 is_recording_(TraceLog::GetInstance()->IsEnabled()), 175 is_recording_(TraceLog::GetInstance()->IsEnabled()),
165 is_monitoring_(false) { 176 is_monitoring_(false) {
166 } 177 }
167 178
168 TracingControllerImpl::~TracingControllerImpl() { 179 TracingControllerImpl::~TracingControllerImpl() {
169 // This is a Leaky instance. 180 // This is a Leaky instance.
170 NOTREACHED(); 181 NOTREACHED();
171 } 182 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 238
228 #if defined(OS_ANDROID) 239 #if defined(OS_ANDROID)
229 if (pending_get_categories_done_callback_.is_null()) 240 if (pending_get_categories_done_callback_.is_null())
230 TraceLog::GetInstance()->AddClockSyncMetadataEvent(); 241 TraceLog::GetInstance()->AddClockSyncMetadataEvent();
231 #endif 242 #endif
232 243
233 options_ = options; 244 options_ = options;
234 int trace_options = (options & RECORD_CONTINUOUSLY) ? 245 int trace_options = (options & RECORD_CONTINUOUSLY) ?
235 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL; 246 TraceLog::RECORD_CONTINUOUSLY : TraceLog::RECORD_UNTIL_FULL;
236 if (options & ENABLE_SAMPLING) { 247 if (options & ENABLE_SAMPLING) {
237 trace_options |= TraceLog::ENABLE_SAMPLING; 248 trace_options |= TraceLog::ENABLE_SAMPLING;
238 } 249 }
239 #if defined(OS_CHROMEOS) 250
240 if (options & ENABLE_SYSTRACE) { 251 if (options & ENABLE_SYSTRACE) {
241 DCHECK(!is_system_tracing_); 252 DCHECK(!is_system_tracing_);
253 #if defined(OS_CHROMEOS)
242 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> 254 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
243 StartSystemTracing(); 255 StartSystemTracing();
244 is_system_tracing_ = true; 256 is_system_tracing_ = true;
257 #elif defined(OS_WIN)
258 is_system_tracing_ =
259 EtwSystemEventConsumer::Get()->StartKernelSessionTracing();
260 EtwSystemEventConsumer::Get()->RequestStartTraceConsuming();
261 #endif
245 } 262 }
246 #endif 263
247 264
248 base::Closure on_enable_recording_done_callback = 265 base::Closure on_enable_recording_done_callback =
249 base::Bind(&TracingControllerImpl::OnEnableRecordingDone, 266 base::Bind(&TracingControllerImpl::OnEnableRecordingDone,
250 base::Unretained(this), 267 base::Unretained(this),
251 category_filter,trace_options, callback); 268 category_filter, trace_options, callback);
252 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 269 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
253 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, 270 base::Bind(&TracingControllerImpl::SetEnabledOnFileThread,
254 base::Unretained(this), 271 base::Unretained(this),
255 category_filter, 272 category_filter,
256 base::debug::TraceLog::RECORDING_MODE, 273 base::debug::TraceLog::RECORDING_MODE,
257 trace_options, 274 trace_options,
258 on_enable_recording_done_callback)); 275 on_enable_recording_done_callback));
259 return true; 276 return true;
260 } 277 }
261 278
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 if (!callback.is_null()) 435 if (!callback.is_null())
419 callback.Run(); 436 callback.Run();
420 } 437 }
421 438
422 void TracingControllerImpl::GetMonitoringStatus( 439 void TracingControllerImpl::GetMonitoringStatus(
423 bool* out_enabled, 440 bool* out_enabled,
424 std::string* out_category_filter, 441 std::string* out_category_filter,
425 TracingController::Options* out_options) { 442 TracingController::Options* out_options) {
426 *out_enabled = is_monitoring_; 443 *out_enabled = is_monitoring_;
427 *out_category_filter = 444 *out_category_filter =
428 TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString(); 445 TraceLog::GetInstance()->GetCurrentCategoryFilter().ToString();
429 *out_options = options_; 446 *out_options = options_;
430 } 447 }
431 448
432 bool TracingControllerImpl::CaptureMonitoringSnapshot( 449 bool TracingControllerImpl::CaptureMonitoringSnapshot(
433 const base::FilePath& result_file_path, 450 const base::FilePath& result_file_path,
434 const TracingFileResultCallback& callback) { 451 const TracingFileResultCallback& callback) {
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
436 453
437 if (!can_disable_monitoring()) 454 if (!can_disable_monitoring())
438 return false; 455 return false;
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 return; 676 return;
660 677
661 OnDisableRecordingComplete(); 678 OnDisableRecordingComplete();
662 } 679 }
663 680
664 void TracingControllerImpl::OnDisableRecordingComplete() { 681 void TracingControllerImpl::OnDisableRecordingComplete() {
665 // All acks (including from the subprocesses and the local trace) have been 682 // All acks (including from the subprocesses and the local trace) have been
666 // received. 683 // received.
667 is_recording_ = false; 684 is_recording_ = false;
668 685
686 if (is_system_tracing_) {
669 #if defined(OS_CHROMEOS) 687 #if defined(OS_CHROMEOS)
670 if (is_system_tracing_) {
671 // Disable system tracing now that the local trace has shutdown. 688 // Disable system tracing now that the local trace has shutdown.
672 // This must be done last because we potentially need to push event 689 // This must be done last because we potentially need to push event
673 // records into the system event log for synchronizing system event 690 // records into the system event log for synchronizing system event
674 // timestamps with chrome event timestamps--and since the system event 691 // 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 692 // 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. 693 // way we're confident we'll have them in the final result.
677 is_system_tracing_ = false; 694 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 // Disable system tracing.
701 EtwSystemEventConsumer::Get()->StopKernelSessionTracing();
702 is_system_tracing_ = false;
703
704 // Request events to be flushed.
705 EtwSystemEventConsumer::Get()->RequestStopTraceConsuming(
706 base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
707 base::Unretained(this)));
708 #endif
682 return; 709 return;
683 } 710 }
684 #endif
685 711
686 // Trigger callback if one is set. 712 // Trigger callback if one is set.
687 if (!pending_get_categories_done_callback_.is_null()) { 713 if (!pending_get_categories_done_callback_.is_null()) {
688 pending_get_categories_done_callback_.Run(known_category_groups_); 714 pending_get_categories_done_callback_.Run(known_category_groups_);
689 pending_get_categories_done_callback_.Reset(); 715 pending_get_categories_done_callback_.Reset();
690 } else if (result_file_) { 716 } else if (result_file_) {
691 result_file_->Close( 717 result_file_->Close(
692 base::Bind(&TracingControllerImpl::OnResultFileClosed, 718 base::Bind(&TracingControllerImpl::OnResultFileClosed,
693 base::Unretained(this))); 719 base::Unretained(this)));
694 } 720 }
695 } 721 }
696 722
697 void TracingControllerImpl::OnResultFileClosed() { 723 void TracingControllerImpl::OnResultFileClosed() {
698 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 724 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
699 725
700 if (!result_file_) 726 if (!result_file_)
701 return; 727 return;
702 728
703 if (!pending_disable_recording_done_callback_.is_null()) { 729 if (!pending_disable_recording_done_callback_.is_null()) {
704 pending_disable_recording_done_callback_.Run(result_file_->path()); 730 pending_disable_recording_done_callback_.Run(result_file_->path());
705 pending_disable_recording_done_callback_.Reset(); 731 pending_disable_recording_done_callback_.Reset();
706 } 732 }
707 result_file_.reset(); 733 result_file_.reset();
708 } 734 }
709 735
710 #if defined(OS_CHROMEOS) 736 #if defined(OS_CHROMEOS) || defined(OS_WIN)
711 void TracingControllerImpl::OnEndSystemTracingAcked( 737 void TracingControllerImpl::OnEndSystemTracingAcked(
712 const scoped_refptr<base::RefCountedString>& events_str_ptr) { 738 const scoped_refptr<base::RefCountedString>& events_str_ptr) {
713 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 739 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
714 740
715 if (result_file_) 741 if (result_file_)
716 result_file_->WriteSystemTrace(events_str_ptr); 742 result_file_->WriteSystemTrace(events_str_ptr);
717 743
718 DCHECK(!is_system_tracing_); 744 DCHECK(!is_system_tracing_);
719 OnDisableRecordingComplete(); 745 OnDisableRecordingComplete();
720 } 746 }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 892 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
867 base::Bind(&TracingControllerImpl::OnWatchEventMatched, 893 base::Bind(&TracingControllerImpl::OnWatchEventMatched,
868 base::Unretained(this))); 894 base::Unretained(this)));
869 return; 895 return;
870 } 896 }
871 897
872 if (!watch_event_callback_.is_null()) 898 if (!watch_event_callback_.is_null())
873 watch_event_callback_.Run(); 899 watch_event_callback_.Run();
874 } 900 }
875 901
876 void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) 902 void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) {
877 {
878 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end()); 903 DCHECK(tracing_uis_.find(tracing_ui) == tracing_uis_.end());
879 tracing_uis_.insert(tracing_ui); 904 tracing_uis_.insert(tracing_ui);
880 } 905 }
881 906
882 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) 907 void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
883 {
884 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui); 908 std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui);
885 DCHECK(it != tracing_uis_.end()); 909 DCHECK(it != tracing_uis_.end());
886 tracing_uis_.erase(it); 910 tracing_uis_.erase(it);
887 } 911 }
888 912
889 void TracingControllerImpl::OnMonitoringStateChanged(bool is_monitoring) 913 void TracingControllerImpl::OnMonitoringStateChanged(bool is_monitoring) {
890 {
891 if (is_monitoring_ == is_monitoring) 914 if (is_monitoring_ == is_monitoring)
892 return; 915 return;
893 916
894 is_monitoring_ = is_monitoring; 917 is_monitoring_ = is_monitoring;
895 #if !defined(OS_ANDROID) 918 #if !defined(OS_ANDROID)
896 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); 919 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin();
897 it != tracing_uis_.end(); it++) { 920 it != tracing_uis_.end(); it++) {
898 (*it)->OnMonitoringStateChanged(is_monitoring); 921 (*it)->OnMonitoringStateChanged(is_monitoring);
899 } 922 }
900 #endif 923 #endif
901 } 924 }
902 925
903 } // namespace content 926 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698