Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled); | 386 uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_enabled); |
| 387 DCHECK(category_ptr >= category_begin && | 387 DCHECK(category_ptr >= category_begin && |
| 388 category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled + | 388 category_ptr < reinterpret_cast<uintptr_t>(g_category_enabled + |
| 389 TRACE_EVENT_MAX_CATEGORIES)) << | 389 TRACE_EVENT_MAX_CATEGORIES)) << |
| 390 "out of bounds category pointer"; | 390 "out of bounds category pointer"; |
| 391 uintptr_t category_index = | 391 uintptr_t category_index = |
| 392 (category_ptr - category_begin) / sizeof(g_category_enabled[0]); | 392 (category_ptr - category_begin) / sizeof(g_category_enabled[0]); |
| 393 return g_categories[category_index]; | 393 return g_categories[category_index]; |
| 394 } | 394 } |
| 395 | 395 |
| 396 static bool DoesCategoryContainMatchingTag(const char* tagged_category, | |
|
nduca
2013/01/28 08:15:28
So this would be DoesCategoryGroupContainCategory
| |
| 397 const char* tag_pattern) { | |
| 398 CStringTokenizer tag_tokens(tagged_category, | |
| 399 tagged_category + strlen(tagged_category), ","); | |
| 400 while (tag_tokens.GetNext()) { | |
| 401 std::string trimmed_tag; | |
| 402 //Trimming tokens to allow categories with arbitrary spacing: | |
| 403 // i.e: "webkit, input" or "webkit , input". | |
| 404 TrimWhitespaceASCII(tag_tokens.token(), TRIM_ALL, &trimmed_tag); | |
|
rterrazas
2013/01/18 17:44:18
I'm thinking that maybe checking if we have leadin
| |
| 405 if(trimmed_tag.length() == 0) | |
| 406 continue; | |
| 407 if (MatchPattern(trimmed_tag.c_str(), tag_pattern)) | |
| 408 return true; | |
| 409 } | |
| 410 return false; | |
| 411 } | |
| 412 | |
| 396 static void EnableMatchingCategory(int category_index, | 413 static void EnableMatchingCategory(int category_index, |
| 397 const std::vector<std::string>& patterns, | 414 const std::vector<std::string>& tag_patterns, |
| 398 unsigned char matched_value, | 415 unsigned char matched_value, |
| 399 unsigned char unmatched_value) { | 416 unsigned char unmatched_value) { |
| 400 std::vector<std::string>::const_iterator ci = patterns.begin(); | 417 std::vector<std::string>::const_iterator ci = tag_patterns.begin(); |
| 401 bool is_match = false; | 418 bool is_match = false; |
| 402 for (; ci != patterns.end(); ++ci) { | 419 for (; ci != tag_patterns.end(); ++ci) { |
| 403 is_match = MatchPattern(g_categories[category_index], ci->c_str()); | 420 is_match = DoesCategoryContainMatchingTag(g_categories[category_index], |
| 421 ci->c_str()); | |
| 404 if (is_match) | 422 if (is_match) |
| 405 break; | 423 break; |
| 406 } | 424 } |
| 407 g_category_enabled[category_index] = is_match ? | 425 g_category_enabled[category_index] = is_match ? |
| 408 matched_value : unmatched_value; | 426 matched_value : unmatched_value; |
| 409 } | 427 } |
| 410 | 428 |
| 411 // Enable/disable each category based on the category filters in |patterns|. | 429 // Enable/disable each category based on the category filters in |tag_patterns|. |
| 412 // If the category name matches one of the patterns, its enabled status is set | 430 // If the category contains a tag that matches one of the tag_patterns, its |
| 413 // to |matched_value|. Otherwise its enabled status is set to |unmatched_value|. | 431 // enabled status is set to |matched_value|. |
| 414 static void EnableMatchingCategories(const std::vector<std::string>& patterns, | 432 // Otherwise its enabled status is set to |unmatched_value|. |
| 415 unsigned char matched_value, | 433 static void EnableMatchingCategories( |
| 416 unsigned char unmatched_value) { | 434 const std::vector<std::string>& tag_patterns, |
| 435 unsigned char matched_value, | |
| 436 unsigned char unmatched_value) { | |
| 417 for (int i = 0; i < g_category_index; i++) | 437 for (int i = 0; i < g_category_index; i++) |
| 418 EnableMatchingCategory(i, patterns, matched_value, unmatched_value); | 438 EnableMatchingCategory(i, tag_patterns, matched_value, unmatched_value); |
| 419 } | 439 } |
| 420 | 440 |
| 421 const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) { | 441 const unsigned char* TraceLog::GetCategoryEnabledInternal(const char* name) { |
| 422 AutoLock lock(lock_); | 442 AutoLock lock(lock_); |
| 423 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote"; | 443 DCHECK(!strchr(name, '"')) << "Category names may not contain double quote"; |
| 424 | 444 |
| 425 unsigned char* category_enabled = NULL; | 445 unsigned char* category_enabled = NULL; |
| 426 // Search for pre-existing category matching this name | 446 // Search for pre-existing category matching this name |
| 427 for (int i = 0; i < g_category_index; i++) { | 447 for (int i = 0; i < g_category_index; i++) { |
| 428 if (strcmp(g_categories[i], name) == 0) { | 448 if (strcmp(g_categories[i], name) == 0) { |
| 429 category_enabled = &g_category_enabled[i]; | 449 category_enabled = &g_category_enabled[i]; |
| 430 break; | 450 break; |
| 431 } | 451 } |
| 432 } | 452 } |
| 433 | 453 |
| 434 if (!category_enabled) { | 454 if (!category_enabled) { |
| 435 // Create a new category | 455 // Create a new category |
| 436 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << | 456 DCHECK(g_category_index < TRACE_EVENT_MAX_CATEGORIES) << |
| 437 "must increase TRACE_EVENT_MAX_CATEGORIES"; | 457 "must increase TRACE_EVENT_MAX_CATEGORIES"; |
| 438 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { | 458 if (g_category_index < TRACE_EVENT_MAX_CATEGORIES) { |
| 439 int new_index = g_category_index++; | 459 int new_index = g_category_index++; |
| 440 // Don't hold on to the name pointer, so that we can create categories | 460 // Don't hold on to the name pointer, so that we can create categories |
| 441 // with strings not known at compile time (this is required by | 461 // with strings not known at compile time (this is required by |
| 442 // SetWatchEvent). | 462 // SetWatchEvent). |
| 443 const char* new_name = base::strdup(name); | 463 const char* new_name = base::strdup(name); |
| 444 ANNOTATE_LEAKING_OBJECT_PTR(new_name); | 464 ANNOTATE_LEAKING_OBJECT_PTR(new_name); |
| 445 g_categories[new_index] = new_name; | 465 g_categories[new_index] = new_name; |
| 446 DCHECK(!g_category_enabled[new_index]); | 466 DCHECK(!g_category_enabled[new_index]); |
| 447 if (enable_count_) { | 467 if (enable_count_) { |
| 448 // Note that if both included and excluded_categories are empty, the | 468 // Note that if both included and excluded_tag_patterns are empty, the |
| 449 // else clause below excludes nothing, thereby enabling this category. | 469 // else clause below excludes nothing, thereby enabling this category. |
| 450 if (!included_categories_.empty()) { | 470 if (!included_tag_patterns_.empty()) { |
| 451 EnableMatchingCategory(new_index, included_categories_, | 471 EnableMatchingCategory(new_index, included_tag_patterns_, |
| 452 CATEGORY_ENABLED, 0); | 472 CATEGORY_ENABLED, 0); |
| 453 } else { | 473 } else { |
| 454 EnableMatchingCategory(new_index, excluded_categories_, | 474 EnableMatchingCategory(new_index, excluded_tag_patterns_, |
| 455 0, CATEGORY_ENABLED); | 475 0, CATEGORY_ENABLED); |
| 456 } | 476 } |
| 457 } else { | 477 } else { |
| 458 g_category_enabled[new_index] = 0; | 478 g_category_enabled[new_index] = 0; |
| 459 } | 479 } |
| 460 category_enabled = &g_category_enabled[new_index]; | 480 category_enabled = &g_category_enabled[new_index]; |
| 461 } else { | 481 } else { |
| 462 category_enabled = &g_category_enabled[g_category_categories_exhausted]; | 482 category_enabled = &g_category_enabled[g_category_categories_exhausted]; |
| 463 } | 483 } |
| 464 } | 484 } |
| 465 #if defined(OS_ANDROID) | 485 #if defined(OS_ANDROID) |
| 466 ApplyATraceEnabledFlag(category_enabled); | 486 ApplyATraceEnabledFlag(category_enabled); |
| 467 #endif | 487 #endif |
| 468 return category_enabled; | 488 return category_enabled; |
| 469 } | 489 } |
| 470 | 490 |
| 471 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { | 491 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { |
| 472 AutoLock lock(lock_); | 492 AutoLock lock(lock_); |
| 473 for (int i = 0; i < g_category_index; i++) | 493 for (int i = 0; i < g_category_index; i++) |
| 474 categories->push_back(g_categories[i]); | 494 categories->push_back(g_categories[i]); |
| 475 } | 495 } |
| 476 | 496 |
| 477 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, | 497 void TraceLog::SetEnabled( |
| 478 const std::vector<std::string>& excluded_categories) { | 498 const std::vector<std::string>& included_tag_patterns, |
| 499 const std::vector<std::string>& excluded_tag_patterns) { | |
| 479 AutoLock lock(lock_); | 500 AutoLock lock(lock_); |
| 480 | |
| 481 if (enable_count_++ > 0) { | 501 if (enable_count_++ > 0) { |
| 482 // Tracing is already enabled, so just merge in enabled categories. | 502 // Tracing is already enabled, so just merge in enabled categories |
| 483 // We only expand the set of enabled categories upon nested SetEnable(). | 503 // We only expand the set of enabled categories upon nested SetEnable(). |
| 484 if (!included_categories_.empty() && !included_categories.empty()) { | 504 if (!included_tag_patterns_.empty() && !included_tag_patterns.empty()) { |
| 485 included_categories_.insert(included_categories_.end(), | 505 included_tag_patterns_.insert(included_tag_patterns_.end(), |
| 486 included_categories.begin(), | 506 included_tag_patterns.begin(), |
| 487 included_categories.end()); | 507 included_tag_patterns.end()); |
| 488 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 508 EnableMatchingCategories(included_tag_patterns_, CATEGORY_ENABLED, 0); |
| 489 } else { | 509 } else { |
| 490 // If either old or new included categories are empty, allow all events. | 510 // If either old or new included categories are empty, allow all events. |
| 491 included_categories_.clear(); | 511 included_tag_patterns_.clear(); |
| 492 excluded_categories_.clear(); | 512 excluded_tag_patterns_.clear(); |
| 493 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 513 EnableMatchingCategories(excluded_tag_patterns_, 0, CATEGORY_ENABLED); |
| 494 } | 514 } |
| 495 return; | 515 return; |
| 496 } | 516 } |
| 497 | 517 |
| 498 if (dispatching_to_observer_list_) { | 518 if (dispatching_to_observer_list_) { |
| 499 DLOG(ERROR) << | 519 DLOG(ERROR) << |
| 500 "Cannot manipulate TraceLog::Enabled state from an observer."; | 520 "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 501 return; | 521 return; |
| 502 } | 522 } |
| 503 | 523 |
| 504 dispatching_to_observer_list_ = true; | 524 dispatching_to_observer_list_ = true; |
| 505 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 525 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
| 506 OnTraceLogWillEnable()); | 526 OnTraceLogWillEnable()); |
| 507 dispatching_to_observer_list_ = false; | 527 dispatching_to_observer_list_ = false; |
| 508 | 528 |
| 509 logged_events_.reserve(1024); | 529 logged_events_.reserve(1024); |
| 510 included_categories_ = included_categories; | 530 included_tag_patterns_ = included_tag_patterns; |
| 511 excluded_categories_ = excluded_categories; | 531 excluded_tag_patterns_ = excluded_tag_patterns; |
| 512 // Note that if both included and excluded_categories are empty, the else | 532 // Note that if both included and excluded_tag_patterns are empty, the else |
| 513 // clause below excludes nothing, thereby enabling all categories. | 533 // clause below excludes nothing, thereby enabling all categories. |
| 514 if (!included_categories_.empty()) | 534 if (!included_tag_patterns_.empty()) |
| 515 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 535 EnableMatchingCategories(included_tag_patterns_, CATEGORY_ENABLED, 0); |
| 516 else | 536 else |
| 517 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 537 EnableMatchingCategories(excluded_tag_patterns_, 0, CATEGORY_ENABLED); |
| 518 } | 538 } |
| 519 | 539 |
| 520 void TraceLog::SetEnabled(const std::string& categories) { | 540 void TraceLog::SetEnabled(const std::string& tag_patterns) { |
| 521 std::vector<std::string> included, excluded; | 541 std::vector<std::string> included, excluded; |
| 522 // Tokenize list of categories, delimited by ','. | 542 // Tokenize list of tag patterns, delimited by ','. |
| 523 StringTokenizer tokens(categories, ","); | 543 StringTokenizer tokens(tag_patterns, ","); |
| 524 while (tokens.GetNext()) { | 544 while (tokens.GetNext()) { |
| 525 bool is_included = true; | 545 bool is_included = true; |
| 526 std::string category = tokens.token(); | 546 std::string tag_pattern = tokens.token(); |
| 527 // Excluded categories start with '-'. | 547 // Excluded tag patterns start with '-'. |
| 528 if (category.at(0) == '-') { | 548 if (tag_pattern.at(0) == '-') { |
| 529 // Remove '-' from category string. | 549 // Remove '-' from tag_pattern string. |
| 530 category = category.substr(1); | 550 tag_pattern = tag_pattern.substr(1); |
| 531 is_included = false; | 551 is_included = false; |
| 532 } | 552 } |
| 533 if (is_included) | 553 if (is_included) |
| 534 included.push_back(category); | 554 included.push_back(tag_pattern); |
| 535 else | 555 else |
| 536 excluded.push_back(category); | 556 excluded.push_back(tag_pattern); |
| 537 } | 557 } |
| 538 SetEnabled(included, excluded); | 558 SetEnabled(included, excluded); |
| 539 } | 559 } |
| 540 | 560 |
| 541 void TraceLog::GetEnabledTraceCategories( | 561 void TraceLog::GetEnabledTraceCategories( |
| 542 std::vector<std::string>* included_out, | 562 std::vector<std::string>* included_out, |
| 543 std::vector<std::string>* excluded_out) { | 563 std::vector<std::string>* excluded_out) { |
| 544 AutoLock lock(lock_); | 564 AutoLock lock(lock_); |
| 545 if (enable_count_) { | 565 if (enable_count_) { |
| 546 *included_out = included_categories_; | 566 *included_out = included_tag_patterns_; |
| 547 *excluded_out = excluded_categories_; | 567 *excluded_out = excluded_tag_patterns_; |
| 548 } | 568 } |
| 549 } | 569 } |
| 550 | 570 |
| 551 void TraceLog::SetDisabled() { | 571 void TraceLog::SetDisabled() { |
| 552 AutoLock lock(lock_); | 572 AutoLock lock(lock_); |
| 553 DCHECK(enable_count_ > 0); | 573 DCHECK(enable_count_ > 0); |
| 554 if (--enable_count_ != 0) | 574 if (--enable_count_ != 0) |
| 555 return; | 575 return; |
| 556 | 576 |
| 557 if (dispatching_to_observer_list_) { | 577 if (dispatching_to_observer_list_) { |
| 558 DLOG(ERROR) | 578 DLOG(ERROR) |
| 559 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 579 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 560 return; | 580 return; |
| 561 } | 581 } |
| 562 | 582 |
| 563 dispatching_to_observer_list_ = true; | 583 dispatching_to_observer_list_ = true; |
| 564 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 584 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
| 565 OnTraceLogWillDisable()); | 585 OnTraceLogWillDisable()); |
| 566 dispatching_to_observer_list_ = false; | 586 dispatching_to_observer_list_ = false; |
| 567 | 587 |
| 568 included_categories_.clear(); | 588 included_tag_patterns_.clear(); |
| 569 excluded_categories_.clear(); | 589 excluded_tag_patterns_.clear(); |
| 570 watch_category_ = NULL; | 590 watch_category_ = NULL; |
| 571 watch_event_name_ = ""; | 591 watch_event_name_ = ""; |
| 572 for (int i = 0; i < g_category_index; i++) | 592 for (int i = 0; i < g_category_index; i++) |
| 573 g_category_enabled[i] = 0; | 593 g_category_enabled[i] = 0; |
| 574 AddThreadNameMetadataEvents(); | 594 AddThreadNameMetadataEvents(); |
| 575 #if defined(OS_ANDROID) | 595 #if defined(OS_ANDROID) |
| 576 AddClockSyncMetadataEvents(); | 596 AddClockSyncMetadataEvents(); |
| 577 #endif | 597 #endif |
| 578 } | 598 } |
| 579 | 599 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 794 unsigned long long pid = static_cast<unsigned long long>(process_id_); | 814 unsigned long long pid = static_cast<unsigned long long>(process_id_); |
| 795 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; | 815 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; |
| 796 } | 816 } |
| 797 | 817 |
| 798 void TraceLog::SetTimeOffset(TimeDelta offset) { | 818 void TraceLog::SetTimeOffset(TimeDelta offset) { |
| 799 time_offset_ = offset; | 819 time_offset_ = offset; |
| 800 } | 820 } |
| 801 | 821 |
| 802 } // namespace debug | 822 } // namespace debug |
| 803 } // namespace base | 823 } // namespace base |
| OLD | NEW |