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

Side by Side Diff: base/trace_event/trace_event_etw_export_win.cc

Issue 1279353002: [ETW Export] Add polling for ETW keyword. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: brucedawson@ comments. Created 5 years, 4 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "base/trace_event/trace_event_etw_export_win.h" 5 #include "base/trace_event/trace_event_etw_export_win.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/strings/string_tokenizer.h" 10 #include "base/strings/string_tokenizer.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/platform_thread.h"
12 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
13 #include "base/trace_event/trace_event_impl.h" 14 #include "base/trace_event/trace_event_impl.h"
14 15
15 // The GetProcAddress technique is borrowed from 16 // The GetProcAddress technique is borrowed from
16 // https://github.com/google/UIforETW/tree/master/ETWProviders 17 // https://github.com/google/UIforETW/tree/master/ETWProviders
17 // 18 //
18 // EVNTAPI is used in evntprov.h which is included by chrome_events_win.h. 19 // EVNTAPI is used in evntprov.h which is included by chrome_events_win.h.
19 // We define EVNTAPI without the DECLSPEC_IMPORT specifier so that we can 20 // We define EVNTAPI without the DECLSPEC_IMPORT specifier so that we can
20 // implement these functions locally instead of using the import library, and 21 // implement these functions locally instead of using the import library, and
21 // can therefore still run on Windows XP. 22 // can therefore still run on Windows XP.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 "toplevel", // 0x200 84 "toplevel", // 0x200
84 "v8", // 0x400 85 "v8", // 0x400
85 "disabled-by-default-cc.debug", // 0x800 86 "disabled-by-default-cc.debug", // 0x800
86 "disabled-by-default-cc.debug.picture", // 0x1000 87 "disabled-by-default-cc.debug.picture", // 0x1000
87 "disabled-by-default-toplevel.flow"}; // 0x2000 88 "disabled-by-default-toplevel.flow"}; // 0x2000
88 const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000 89 const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000
89 const char* disabled_other_events_group_name = 90 const char* disabled_other_events_group_name =
90 "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000 91 "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000
91 uint64 other_events_keyword_bit = 1ULL << 61; 92 uint64 other_events_keyword_bit = 1ULL << 61;
92 uint64 disabled_other_events_keyword_bit = 1ULL << 62; 93 uint64 disabled_other_events_keyword_bit = 1ULL << 62;
94
95 // This object will be created by each process. It's a background (low-priority)
96 // thread that will monitor the ETW keyword for any changes..
dsinclair 2015/08/11 19:33:14 nit: double .'s at end.
Georges Khalil 2015/08/12 17:24:25 Done.
97 class ETWKeywordUpdateThread : public base::PlatformThread::Delegate {
98 public:
99 ETWKeywordUpdateThread() {}
100 ~ETWKeywordUpdateThread() override {}
101
102 // Implementation of PlatformThread::Delegate:
103 void ThreadMain() override {
104 base::PlatformThread::SetName("ETW Keyword Update Thread");
105 while (1) {
106 base::PlatformThread::Sleep(
107 base::TimeDelta::FromMilliseconds(kUpdateTimerDelayMs));
dsinclair 2015/08/11 19:33:14 Why do the milliseconds conversion every iteration
Georges Khalil 2015/08/12 17:24:25 Done.
108 base::trace_event::TraceEventETWExport::UpdateETWKeyword();
109 }
110 }
111
112 private:
113 // Time between checks for ETW keyword changes (in milliseconds).
114 unsigned int kUpdateTimerDelayMs = 1000;
115 };
116
93 } // namespace 117 } // namespace
94 118
95 // Redirector function for EventRegister. Called by macros in 119 // Redirector function for EventRegister. Called by macros in
96 // chrome_events_win.h 120 // chrome_events_win.h
97 ULONG EVNTAPI EventRegister(LPCGUID ProviderId, 121 ULONG EVNTAPI EventRegister(LPCGUID ProviderId,
98 PENABLECALLBACK EnableCallback, 122 PENABLECALLBACK EnableCallback,
99 PVOID CallbackContext, 123 PVOID CallbackContext,
100 PREGHANDLE RegHandle) { 124 PREGHANDLE RegHandle) {
101 if (EventRegisterProc) 125 if (EventRegisterProc)
102 return EventRegisterProc(ProviderId, EnableCallback, CallbackContext, 126 return EventRegisterProc(ProviderId, EnableCallback, CallbackContext,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 ::GetProcAddress(AdvapiDLL, "EventRegister")); 161 ::GetProcAddress(AdvapiDLL, "EventRegister"));
138 EventWriteProc = reinterpret_cast<tEventWrite>( 162 EventWriteProc = reinterpret_cast<tEventWrite>(
139 ::GetProcAddress(AdvapiDLL, "EventWrite")); 163 ::GetProcAddress(AdvapiDLL, "EventWrite"));
140 EventUnregisterProc = reinterpret_cast<tEventUnregister>( 164 EventUnregisterProc = reinterpret_cast<tEventUnregister>(
141 ::GetProcAddress(AdvapiDLL, "EventUnregister")); 165 ::GetProcAddress(AdvapiDLL, "EventUnregister"));
142 166
143 // Register the ETW provider. If registration fails then the event logging 167 // Register the ETW provider. If registration fails then the event logging
144 // calls will fail (on XP this call will do nothing). 168 // calls will fail (on XP this call will do nothing).
145 EventRegisterChrome(); 169 EventRegisterChrome();
146 170
147 UpdateEnabledCategories(); 171 UpdateEnabledCategories();
Georges Khalil 2015/08/12 17:24:25 I removed this from here and moved it to EnableETW
148 } 172 }
149 } 173 }
150 174
151 TraceEventETWExport::~TraceEventETWExport() { 175 TraceEventETWExport::~TraceEventETWExport() {
152 EventUnregisterChrome(); 176 EventUnregisterChrome();
153 } 177 }
154 178
155 // static 179 // static
156 TraceEventETWExport* TraceEventETWExport::GetInstance() { 180 TraceEventETWExport* TraceEventETWExport::GetInstance() {
157 return Singleton<TraceEventETWExport, 181 return Singleton<TraceEventETWExport,
158 StaticMemorySingletonTraits<TraceEventETWExport>>::get(); 182 StaticMemorySingletonTraits<TraceEventETWExport>>::get();
159 } 183 }
160 184
161 // static 185 // static
162 void TraceEventETWExport::EnableETWExport() { 186 void TraceEventETWExport::EnableETWExport() {
163 if (GetInstance()) 187 auto* instance = GetInstance();
164 GetInstance()->etw_export_enabled_ = true; 188 if (instance && !instance->etw_export_enabled_) {
189 instance->etw_export_enabled_ = true;
190 // We only create the update thread once and it lives for as long as Chrome
191 // is running.
192 if (instance->keyword_update_thread_handle_.is_null()) {
193 instance->keyword_update_thread_.reset(new ETWKeywordUpdateThread);
194 PlatformThread::CreateWithPriority(
195 0, instance ->keyword_update_thread_.get(),
dsinclair 2015/08/11 19:33:14 nit: Remove space between instance and ->
Georges Khalil 2015/08/12 17:24:25 Done.
196 &instance->keyword_update_thread_handle_,
197 ThreadPriority::BACKGROUND);
198 }
199 }
165 } 200 }
166 201
167 // static 202 // static
168 void TraceEventETWExport::DisableETWExport() { 203 void TraceEventETWExport::DisableETWExport() {
169 if (GetInstance()) 204 auto* instance = GetInstance();
170 GetInstance()->etw_export_enabled_ = false; 205 if (instance && instance->etw_export_enabled_)
206 instance->etw_export_enabled_ = false;
171 } 207 }
dsinclair 2015/08/11 19:33:14 Why don't we shut down the thread at the point we
brucedawson 2015/08/11 20:24:02 Currently this function is never called - there is
Georges Khalil 2015/08/12 17:24:25 Exactly. This might change down the road when we c
dsinclair 2015/08/13 19:03:17 If it's unused, we should probably use it as it's
172 208
173 // static 209 // static
174 bool TraceEventETWExport::IsETWExportEnabled() { 210 bool TraceEventETWExport::IsETWExportEnabled() {
175 return (GetInstance() && GetInstance()->etw_export_enabled_); 211 auto* instance = GetInstance();
212 return (instance && instance->etw_export_enabled_);
176 } 213 }
177 214
178 // static 215 // static
179 void TraceEventETWExport::AddEvent( 216 void TraceEventETWExport::AddEvent(
180 char phase, 217 char phase,
181 const unsigned char* category_group_enabled, 218 const unsigned char* category_group_enabled,
182 const char* name, 219 const char* name,
183 unsigned long long id, 220 unsigned long long id,
184 int num_args, 221 int num_args,
185 const char** arg_names, 222 const char** arg_names,
186 const unsigned char* arg_types, 223 const unsigned char* arg_types,
187 const unsigned long long* arg_values, 224 const unsigned long long* arg_values,
188 const scoped_refptr<ConvertableToTraceFormat>* convertable_values) { 225 const scoped_refptr<ConvertableToTraceFormat>* convertable_values) {
189 // We bail early in case exporting is disabled or no consumer is listening. 226 // We bail early in case exporting is disabled or no consumer is listening.
190 if (!GetInstance() || !GetInstance()->etw_export_enabled_ || 227 auto* instance = GetInstance();
228 if (!instance || !instance->etw_export_enabled_ ||
191 !EventEnabledChromeEvent()) 229 !EventEnabledChromeEvent())
192 return; 230 return;
193 231
194 const char* phase_string = nullptr; 232 const char* phase_string = nullptr;
195 // Space to store the phase identifier and null-terminator, when needed. 233 // Space to store the phase identifier and null-terminator, when needed.
196 char phase_buffer[2]; 234 char phase_buffer[2];
197 switch (phase) { 235 switch (phase) {
198 case TRACE_EVENT_PHASE_BEGIN: 236 case TRACE_EVENT_PHASE_BEGIN:
199 phase_string = "Begin"; 237 phase_string = "Begin";
200 break; 238 break;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 325
288 // static 326 // static
289 void TraceEventETWExport::AddCustomEvent(const char* name, 327 void TraceEventETWExport::AddCustomEvent(const char* name,
290 char const* phase, 328 char const* phase,
291 const char* arg_name_1, 329 const char* arg_name_1,
292 const char* arg_value_1, 330 const char* arg_value_1,
293 const char* arg_name_2, 331 const char* arg_name_2,
294 const char* arg_value_2, 332 const char* arg_value_2,
295 const char* arg_name_3, 333 const char* arg_name_3,
296 const char* arg_value_3) { 334 const char* arg_value_3) {
297 if (!GetInstance() || !GetInstance()->etw_export_enabled_ || 335 auto* instance = GetInstance();
336 if (!instance || !instance->etw_export_enabled_ ||
298 !EventEnabledChromeEvent()) 337 !EventEnabledChromeEvent())
299 return; 338 return;
300 339
301 EventWriteChromeEvent(name, phase, arg_name_1, arg_value_1, arg_name_2, 340 EventWriteChromeEvent(name, phase, arg_name_1, arg_value_1, arg_name_2,
302 arg_value_2, arg_name_3, arg_value_3); 341 arg_value_2, arg_name_3, arg_value_3);
303 } 342 }
304 343
305 // static 344 // static
306 bool TraceEventETWExport::IsCategoryGroupEnabled( 345 bool TraceEventETWExport::IsCategoryGroupEnabled(
307 const char* category_group_name) { 346 const char* category_group_name) {
308 DCHECK(category_group_name); 347 DCHECK(category_group_name);
309 auto instance = GetInstance(); 348 auto* instance = GetInstance();
310 if (instance == nullptr) 349 if (instance == nullptr)
311 return false; 350 return false;
312 351
313 if (!instance->IsETWExportEnabled()) 352 if (!instance->IsETWExportEnabled())
314 return false; 353 return false;
315 354
316 CStringTokenizer category_group_tokens( 355 CStringTokenizer category_group_tokens(
317 category_group_name, category_group_name + strlen(category_group_name), 356 category_group_name, category_group_name + strlen(category_group_name),
318 ","); 357 ",");
319 while (category_group_tokens.GetNext()) { 358 while (category_group_tokens.GetNext()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 DCHECK(categories_status_.find(disabled_other_events_group_name) != 408 DCHECK(categories_status_.find(disabled_other_events_group_name) !=
370 categories_status_.end()); 409 categories_status_.end());
371 return categories_status_.find(disabled_other_events_group_name)->second; 410 return categories_status_.find(disabled_other_events_group_name)->second;
372 } else { 411 } else {
373 DCHECK(categories_status_.find(other_events_group_name) != 412 DCHECK(categories_status_.find(other_events_group_name) !=
374 categories_status_.end()); 413 categories_status_.end());
375 return categories_status_.find(other_events_group_name)->second; 414 return categories_status_.find(other_events_group_name)->second;
376 } 415 }
377 } 416 }
378 417
418 // static
419 void TraceEventETWExport::UpdateETWKeyword() {
420 auto* instance = GetInstance();
421 DCHECK(instance);
422 if (IsETWExportEnabled()) {
dsinclair 2015/08/11 19:33:14 if (!IsETWExportEnabled()) return; if (!instance
Georges Khalil 2015/08/12 17:24:25 I changed this. Now UpdateEnabledCategories calls
423 if (instance->UpdateEnabledCategories())
424 TraceLog::GetInstance()->UpdateCategoryGroupEnabledFlags();
425 }
426 }
379 } // namespace trace_event 427 } // namespace trace_event
380 } // namespace base 428 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698