Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 "toplevel", // 0x200 | 83 "toplevel", // 0x200 |
| 84 "v8", // 0x400 | 84 "v8", // 0x400 |
| 85 "disabled-by-default-cc.debug", // 0x800 | 85 "disabled-by-default-cc.debug", // 0x800 |
| 86 "disabled-by-default-cc.debug.picture", // 0x1000 | 86 "disabled-by-default-cc.debug.picture", // 0x1000 |
| 87 "disabled-by-default-toplevel.flow"}; // 0x2000 | 87 "disabled-by-default-toplevel.flow"}; // 0x2000 |
| 88 const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000 | 88 const char* other_events_group_name = "__OTHER_EVENTS"; // 0x2000000000000000 |
| 89 const char* disabled_other_events_group_name = | 89 const char* disabled_other_events_group_name = |
| 90 "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000 | 90 "__DISABLED_OTHER_EVENTS"; // 0x4000000000000000 |
| 91 uint64 other_events_keyword_bit = 1ULL << 61; | 91 uint64 other_events_keyword_bit = 1ULL << 61; |
| 92 uint64 disabled_other_events_keyword_bit = 1ULL << 62; | 92 uint64 disabled_other_events_keyword_bit = 1ULL << 62; |
| 93 | |
| 94 // Time between checks for ETW keyword changes (in milliseconds). | |
| 95 unsigned int kUpdateTimerDelayMs = 1000; | |
| 93 } // namespace | 96 } // namespace |
| 94 | 97 |
| 95 // Redirector function for EventRegister. Called by macros in | 98 // Redirector function for EventRegister. Called by macros in |
| 96 // chrome_events_win.h | 99 // chrome_events_win.h |
| 97 ULONG EVNTAPI EventRegister(LPCGUID ProviderId, | 100 ULONG EVNTAPI EventRegister(LPCGUID ProviderId, |
| 98 PENABLECALLBACK EnableCallback, | 101 PENABLECALLBACK EnableCallback, |
| 99 PVOID CallbackContext, | 102 PVOID CallbackContext, |
| 100 PREGHANDLE RegHandle) { | 103 PREGHANDLE RegHandle) { |
| 101 if (EventRegisterProc) | 104 if (EventRegisterProc) |
| 102 return EventRegisterProc(ProviderId, EnableCallback, CallbackContext, | 105 return EventRegisterProc(ProviderId, EnableCallback, CallbackContext, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 GetInstance()->etw_export_enabled_ = true; | 167 GetInstance()->etw_export_enabled_ = true; |
| 165 } | 168 } |
| 166 | 169 |
| 167 // static | 170 // static |
| 168 void TraceEventETWExport::DisableETWExport() { | 171 void TraceEventETWExport::DisableETWExport() { |
| 169 if (GetInstance()) | 172 if (GetInstance()) |
| 170 GetInstance()->etw_export_enabled_ = false; | 173 GetInstance()->etw_export_enabled_ = false; |
| 171 } | 174 } |
| 172 | 175 |
| 173 // static | 176 // static |
| 177 bool TraceEventETWExport::IsETWExportEnabled() { | |
| 178 return (GetInstance() && GetInstance()->etw_export_enabled_); | |
|
brucedawson
2015/06/26 22:24:24
If you move this and change it in the same CL then
| |
| 179 } | |
| 180 | |
| 181 // static | |
| 174 void TraceEventETWExport::AddEvent( | 182 void TraceEventETWExport::AddEvent( |
| 175 char phase, | 183 char phase, |
| 176 const unsigned char* category_group_enabled, | 184 const unsigned char* category_group_enabled, |
| 177 const char* name, | 185 const char* name, |
| 178 unsigned long long id, | 186 unsigned long long id, |
| 179 int num_args, | 187 int num_args, |
| 180 const char** arg_names, | 188 const char** arg_names, |
| 181 const unsigned char* arg_types, | 189 const unsigned char* arg_types, |
| 182 const unsigned long long* arg_values, | 190 const unsigned long long* arg_values, |
| 183 const scoped_refptr<ConvertableToTraceFormat>* convertable_values) { | 191 const scoped_refptr<ConvertableToTraceFormat>* convertable_values) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 const char* arg_name_3, | 298 const char* arg_name_3, |
| 291 const char* arg_value_3) { | 299 const char* arg_value_3) { |
| 292 if (!GetInstance() || !GetInstance()->etw_export_enabled_ || | 300 if (!GetInstance() || !GetInstance()->etw_export_enabled_ || |
| 293 !EventEnabledChromeEvent()) | 301 !EventEnabledChromeEvent()) |
| 294 return; | 302 return; |
| 295 | 303 |
| 296 EventWriteChromeEvent(name, phase, arg_name_1, arg_value_1, arg_name_2, | 304 EventWriteChromeEvent(name, phase, arg_name_1, arg_value_1, arg_name_2, |
| 297 arg_value_2, arg_name_3, arg_value_3); | 305 arg_value_2, arg_name_3, arg_value_3); |
| 298 } | 306 } |
| 299 | 307 |
| 300 void TraceEventETWExport::Resurrect() { | |
| 301 StaticMemorySingletonTraits<TraceEventETWExport>::Resurrect(); | |
| 302 } | |
| 303 | |
| 304 // static | 308 // static |
| 305 bool TraceEventETWExport::IsCategoryGroupEnabled( | 309 bool TraceEventETWExport::IsCategoryGroupEnabled( |
| 306 const char* category_group_name) { | 310 const char* category_group_name) { |
| 307 DCHECK(category_group_name); | 311 DCHECK(category_group_name); |
| 308 auto instance = GetInstance(); | 312 auto instance = GetInstance(); |
| 309 if (instance == nullptr) | 313 if (instance == nullptr) |
| 310 return false; | 314 return false; |
| 311 | 315 |
| 312 if (!instance->IsETWExportEnabled()) | 316 if (!instance->IsETWExportEnabled()) |
| 313 return false; | 317 return false; |
| 314 | 318 |
| 315 CStringTokenizer category_group_tokens( | 319 CStringTokenizer category_group_tokens( |
| 316 category_group_name, category_group_name + strlen(category_group_name), | 320 category_group_name, category_group_name + strlen(category_group_name), |
| 317 ","); | 321 ","); |
| 318 while (category_group_tokens.GetNext()) { | 322 while (category_group_tokens.GetNext()) { |
| 319 std::string category_group_token = category_group_tokens.token(); | 323 std::string category_group_token = category_group_tokens.token(); |
| 320 if (instance->IsCategoryEnabled(category_group_token.c_str())) { | 324 if (instance->IsCategoryEnabled(category_group_token.c_str())) { |
| 321 return true; | 325 return true; |
| 322 } | 326 } |
| 323 } | 327 } |
| 324 return false; | 328 return false; |
| 325 } | 329 } |
| 326 | 330 |
| 327 void TraceEventETWExport::UpdateEnabledCategories() { | 331 // static |
| 332 void TraceEventETWExport::StartKeywordUpdateTimer() { | |
| 333 if (IsETWExportEnabled()) { | |
| 334 GetInstance()->keyword_update_timer_.Start( | |
| 335 FROM_HERE, base::TimeDelta::FromMilliseconds(kUpdateTimerDelayMs), | |
| 336 base::Bind(&TraceEventETWExport::KeywordUpdateTimerCallback)); | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 void TraceEventETWExport::Resurrect() { | |
| 341 StaticMemorySingletonTraits<TraceEventETWExport>::Resurrect(); | |
| 342 } | |
| 343 | |
| 344 bool TraceEventETWExport::UpdateEnabledCategories() { | |
| 345 if (etw_match_any_keyword_ == CHROME_Context.MatchAnyKeyword) | |
| 346 return false; | |
| 347 | |
| 328 // If the keyword has changed, update each category. | 348 // If the keyword has changed, update each category. |
| 329 // Chrome_Context.MatchAnyKeyword is set by UIforETW (or other ETW trace | 349 // Chrome_Context.MatchAnyKeyword is set by UIforETW (or other ETW trace |
| 330 // recording tools) using the ETW infrastructure. This value will be set in | 350 // recording tools) using the ETW infrastructure. This value will be set in |
| 331 // all Chrome processes that have registered their ETW provider. | 351 // all Chrome processes that have registered their ETW provider. |
| 332 if (etw_match_any_keyword_ != CHROME_Context.MatchAnyKeyword) { | 352 etw_match_any_keyword_ = CHROME_Context.MatchAnyKeyword; |
| 333 etw_match_any_keyword_ = CHROME_Context.MatchAnyKeyword; | 353 for (int i = 0; i < ARRAYSIZE(filtered_event_group_names); i++) { |
| 334 for (int i = 0; i < ARRAYSIZE(filtered_event_group_names); i++) { | 354 if (etw_match_any_keyword_ & (1ULL << i)) { |
| 335 if (etw_match_any_keyword_ & (1ULL << i)) { | 355 categories_status_[filtered_event_group_names[i]] = true; |
| 336 categories_status_[filtered_event_group_names[i]] = true; | 356 } else { |
| 337 } else { | 357 categories_status_[filtered_event_group_names[i]] = false; |
| 338 categories_status_[filtered_event_group_names[i]] = false; | |
| 339 } | |
| 340 } | 358 } |
| 341 } | 359 } |
| 360 | |
| 342 // Also update the two default categories. | 361 // Also update the two default categories. |
| 343 if (etw_match_any_keyword_ & other_events_keyword_bit) { | 362 if (etw_match_any_keyword_ & other_events_keyword_bit) { |
| 344 categories_status_[other_events_group_name] = true; | 363 categories_status_[other_events_group_name] = true; |
| 345 } else { | 364 } else { |
| 346 categories_status_[other_events_group_name] = false; | 365 categories_status_[other_events_group_name] = false; |
| 347 } | 366 } |
| 348 if (etw_match_any_keyword_ & disabled_other_events_keyword_bit) { | 367 if (etw_match_any_keyword_ & disabled_other_events_keyword_bit) { |
| 349 categories_status_[disabled_other_events_group_name] = true; | 368 categories_status_[disabled_other_events_group_name] = true; |
| 350 } else { | 369 } else { |
| 351 categories_status_[disabled_other_events_group_name] = false; | 370 categories_status_[disabled_other_events_group_name] = false; |
| 352 } | 371 } |
| 372 | |
| 373 return true; | |
| 353 } | 374 } |
| 354 | 375 |
| 355 bool TraceEventETWExport::IsCategoryEnabled(const char* category_name) const { | 376 bool TraceEventETWExport::IsCategoryEnabled(const char* category_name) const { |
| 356 // Try to find the category and return its status if found | 377 // Try to find the category and return its status if found |
| 357 auto it = categories_status_.find(category_name); | 378 auto it = categories_status_.find(category_name); |
| 358 if (it != categories_status_.end()) | 379 if (it != categories_status_.end()) |
| 359 return it->second; | 380 return it->second; |
| 360 | 381 |
| 361 // Otherwise return the corresponding default status by first checking if the | 382 // Otherwise return the corresponding default status by first checking if the |
| 362 // category is disabled by default. | 383 // category is disabled by default. |
| 363 if (StringPiece(category_name).starts_with("disabled-by-default")) { | 384 if (StringPiece(category_name).starts_with("disabled-by-default")) { |
| 364 DCHECK(categories_status_.find(disabled_other_events_group_name) != | 385 DCHECK(categories_status_.find(disabled_other_events_group_name) != |
| 365 categories_status_.end()); | 386 categories_status_.end()); |
| 366 return categories_status_.find(disabled_other_events_group_name)->second; | 387 return categories_status_.find(disabled_other_events_group_name)->second; |
| 367 } else { | 388 } else { |
| 368 DCHECK(categories_status_.find(other_events_group_name) != | 389 DCHECK(categories_status_.find(other_events_group_name) != |
| 369 categories_status_.end()); | 390 categories_status_.end()); |
| 370 return categories_status_.find(other_events_group_name)->second; | 391 return categories_status_.find(other_events_group_name)->second; |
| 371 } | 392 } |
| 372 } | 393 } |
| 373 | 394 |
| 395 // static | |
| 396 void TraceEventETWExport::KeywordUpdateTimerCallback() { | |
| 397 DCHECK(GetInstance()); | |
| 398 if (IsETWExportEnabled()) { | |
| 399 if (GetInstance()->UpdateEnabledCategories()) | |
| 400 TraceLog::GetInstance()->UpdateCategoryGroupEnabledFlags(); | |
| 401 } | |
| 402 } | |
| 374 } // namespace trace_event | 403 } // namespace trace_event |
| 375 } // namespace base | 404 } // namespace base |
| OLD | NEW |