| 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" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/memory/singleton.h" | 14 #include "base/memory/singleton.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/string_split.h" |
| 17 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 18 #include "base/stringprintf.h" | 19 #include "base/stringprintf.h" |
| 19 #include "base/strings/string_tokenizer.h" | 20 #include "base/strings/string_tokenizer.h" |
| 20 #include "base/sys_info.h" | 21 #include "base/sys_info.h" |
| 21 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 22 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 22 #include "base/threading/platform_thread.h" | 23 #include "base/threading/platform_thread.h" |
| 23 #include "base/threading/thread_id_name_manager.h" | 24 #include "base/threading/thread_id_name_manager.h" |
| 24 #include "base/threading/thread_local.h" | 25 #include "base/threading/thread_local.h" |
| 25 #include "base/time.h" | 26 #include "base/time.h" |
| 26 #include "base/utf_string_conversions.h" | 27 #include "base/utf_string_conversions.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 const int g_category_categories_exhausted = 1; | 66 const int g_category_categories_exhausted = 1; |
| 66 const int g_category_metadata = 2; | 67 const int g_category_metadata = 2; |
| 67 int g_category_index = 3; // skip initial 3 categories | 68 int g_category_index = 3; // skip initial 3 categories |
| 68 | 69 |
| 69 // The name of the current thread. This is used to decide if the current | 70 // The name of the current thread. This is used to decide if the current |
| 70 // thread name has changed. We combine all the seen thread names into the | 71 // thread name has changed. We combine all the seen thread names into the |
| 71 // output name for the thread. | 72 // output name for the thread. |
| 72 LazyInstance<ThreadLocalPointer<const char> >::Leaky | 73 LazyInstance<ThreadLocalPointer<const char> >::Leaky |
| 73 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; | 74 g_current_thread_name = LAZY_INSTANCE_INITIALIZER; |
| 74 | 75 |
| 76 const char kRecordUntilFull[] = "record-until-full"; |
| 77 |
| 75 } // namespace | 78 } // namespace |
| 76 | 79 |
| 77 //////////////////////////////////////////////////////////////////////////////// | 80 //////////////////////////////////////////////////////////////////////////////// |
| 78 // | 81 // |
| 79 // TraceEvent | 82 // TraceEvent |
| 80 // | 83 // |
| 81 //////////////////////////////////////////////////////////////////////////////// | 84 //////////////////////////////////////////////////////////////////////////////// |
| 82 | 85 |
| 83 namespace { | 86 namespace { |
| 84 | 87 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 void TraceLog::NotificationHelper::SendNotificationIfAny() { | 344 void TraceLog::NotificationHelper::SendNotificationIfAny() { |
| 342 if (notification_) | 345 if (notification_) |
| 343 callback_copy_.Run(notification_); | 346 callback_copy_.Run(notification_); |
| 344 } | 347 } |
| 345 | 348 |
| 346 // static | 349 // static |
| 347 TraceLog* TraceLog::GetInstance() { | 350 TraceLog* TraceLog::GetInstance() { |
| 348 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); | 351 return Singleton<TraceLog, StaticMemorySingletonTraits<TraceLog> >::get(); |
| 349 } | 352 } |
| 350 | 353 |
| 354 // static |
| 355 // Note, if you add more options here you also need to update: |
| 356 // content/browser/devtools/devtools_tracing_handler:TraceOptionsFromString |
| 357 TraceLog::Options TraceLog::TraceOptionsFromString(const std::string& options) { |
| 358 std::vector<std::string> split; |
| 359 base::SplitString(options, ',', &split); |
| 360 int ret = 0; |
| 361 for (std::vector<std::string>::iterator iter = split.begin(); |
| 362 iter != split.end(); |
| 363 ++iter) { |
| 364 if (*iter == kRecordUntilFull) { |
| 365 ret |= RECORD_UNTIL_FULL; |
| 366 } else { |
| 367 NOTREACHED(); // Unknown option provided. |
| 368 } |
| 369 } |
| 370 // Check to see if any RECORD_* options are set, and if none, then provide |
| 371 // a default. |
| 372 // TODO(dsinclair): Remove this comment when we have more then one RECORD_* |
| 373 // flag and the code's structure is then sensible. |
| 374 if (!(ret & RECORD_UNTIL_FULL)) |
| 375 ret |= RECORD_UNTIL_FULL; // Default when no options are specified. |
| 376 |
| 377 return static_cast<Options>(ret); |
| 378 } |
| 379 |
| 351 TraceLog::TraceLog() | 380 TraceLog::TraceLog() |
| 352 : enable_count_(0), | 381 : enable_count_(0), |
| 353 dispatching_to_observer_list_(false), | 382 dispatching_to_observer_list_(false), |
| 354 watch_category_(NULL) { | 383 watch_category_(NULL), |
| 384 trace_options_(RECORD_UNTIL_FULL) { |
| 355 // Trace is enabled or disabled on one thread while other threads are | 385 // Trace is enabled or disabled on one thread while other threads are |
| 356 // accessing the enabled flag. We don't care whether edge-case events are | 386 // accessing the enabled flag. We don't care whether edge-case events are |
| 357 // traced or not, so we allow races on the enabled flag to keep the trace | 387 // traced or not, so we allow races on the enabled flag to keep the trace |
| 358 // macros fast. | 388 // macros fast. |
| 359 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 389 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
| 360 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), | 390 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), |
| 361 // "trace_event category enabled"); | 391 // "trace_event category enabled"); |
| 362 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { | 392 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { |
| 363 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], | 393 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], |
| 364 "trace_event category enabled"); | 394 "trace_event category enabled"); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 return category_enabled; | 501 return category_enabled; |
| 472 } | 502 } |
| 473 | 503 |
| 474 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { | 504 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { |
| 475 AutoLock lock(lock_); | 505 AutoLock lock(lock_); |
| 476 for (int i = 0; i < g_category_index; i++) | 506 for (int i = 0; i < g_category_index; i++) |
| 477 categories->push_back(g_categories[i]); | 507 categories->push_back(g_categories[i]); |
| 478 } | 508 } |
| 479 | 509 |
| 480 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, | 510 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, |
| 481 const std::vector<std::string>& excluded_categories) { | 511 const std::vector<std::string>& excluded_categories, |
| 512 Options options) { |
| 482 AutoLock lock(lock_); | 513 AutoLock lock(lock_); |
| 483 | 514 |
| 484 if (enable_count_++ > 0) { | 515 if (enable_count_++ > 0) { |
| 516 if (options != trace_options_) { |
| 517 DLOG(ERROR) << "Attemting to re-enable tracing with a different " |
| 518 << "set of options."; |
| 519 } |
| 520 |
| 485 // Tracing is already enabled, so just merge in enabled categories. | 521 // Tracing is already enabled, so just merge in enabled categories. |
| 486 // We only expand the set of enabled categories upon nested SetEnable(). | 522 // We only expand the set of enabled categories upon nested SetEnable(). |
| 487 if (!included_categories_.empty() && !included_categories.empty()) { | 523 if (!included_categories_.empty() && !included_categories.empty()) { |
| 488 included_categories_.insert(included_categories_.end(), | 524 included_categories_.insert(included_categories_.end(), |
| 489 included_categories.begin(), | 525 included_categories.begin(), |
| 490 included_categories.end()); | 526 included_categories.end()); |
| 491 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 527 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); |
| 492 } else { | 528 } else { |
| 493 // If either old or new included categories are empty, allow all events. | 529 // If either old or new included categories are empty, allow all events. |
| 494 included_categories_.clear(); | 530 included_categories_.clear(); |
| 495 excluded_categories_.clear(); | 531 excluded_categories_.clear(); |
| 496 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 532 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); |
| 497 } | 533 } |
| 498 return; | 534 return; |
| 499 } | 535 } |
| 536 trace_options_ = options; |
| 500 | 537 |
| 501 if (dispatching_to_observer_list_) { | 538 if (dispatching_to_observer_list_) { |
| 502 DLOG(ERROR) << | 539 DLOG(ERROR) << |
| 503 "Cannot manipulate TraceLog::Enabled state from an observer."; | 540 "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 504 return; | 541 return; |
| 505 } | 542 } |
| 506 | 543 |
| 507 dispatching_to_observer_list_ = true; | 544 dispatching_to_observer_list_ = true; |
| 508 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 545 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
| 509 OnTraceLogWillEnable()); | 546 OnTraceLogWillEnable()); |
| 510 dispatching_to_observer_list_ = false; | 547 dispatching_to_observer_list_ = false; |
| 511 | 548 |
| 512 logged_events_.reserve(1024); | 549 logged_events_.reserve(1024); |
| 513 included_categories_ = included_categories; | 550 included_categories_ = included_categories; |
| 514 excluded_categories_ = excluded_categories; | 551 excluded_categories_ = excluded_categories; |
| 515 // Note that if both included and excluded_categories are empty, the else | 552 // Note that if both included and excluded_categories are empty, the else |
| 516 // clause below excludes nothing, thereby enabling all categories. | 553 // clause below excludes nothing, thereby enabling all categories. |
| 517 if (!included_categories_.empty()) | 554 if (!included_categories_.empty()) |
| 518 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 555 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); |
| 519 else | 556 else |
| 520 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 557 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); |
| 521 } | 558 } |
| 522 | 559 |
| 523 void TraceLog::SetEnabled(const std::string& categories) { | 560 void TraceLog::SetEnabled(const std::string& categories, Options options) { |
| 524 std::vector<std::string> included, excluded; | 561 std::vector<std::string> included, excluded; |
| 525 // Tokenize list of categories, delimited by ','. | 562 // Tokenize list of categories, delimited by ','. |
| 526 StringTokenizer tokens(categories, ","); | 563 StringTokenizer tokens(categories, ","); |
| 527 while (tokens.GetNext()) { | 564 while (tokens.GetNext()) { |
| 528 bool is_included = true; | 565 bool is_included = true; |
| 529 std::string category = tokens.token(); | 566 std::string category = tokens.token(); |
| 530 // Excluded categories start with '-'. | 567 // Excluded categories start with '-'. |
| 531 if (category.at(0) == '-') { | 568 if (category.at(0) == '-') { |
| 532 // Remove '-' from category string. | 569 // Remove '-' from category string. |
| 533 category = category.substr(1); | 570 category = category.substr(1); |
| 534 is_included = false; | 571 is_included = false; |
| 535 } | 572 } |
| 536 if (is_included) | 573 if (is_included) |
| 537 included.push_back(category); | 574 included.push_back(category); |
| 538 else | 575 else |
| 539 excluded.push_back(category); | 576 excluded.push_back(category); |
| 540 } | 577 } |
| 541 SetEnabled(included, excluded); | 578 SetEnabled(included, excluded, options); |
| 542 } | 579 } |
| 543 | 580 |
| 544 void TraceLog::GetEnabledTraceCategories( | 581 void TraceLog::GetEnabledTraceCategories( |
| 545 std::vector<std::string>* included_out, | 582 std::vector<std::string>* included_out, |
| 546 std::vector<std::string>* excluded_out) { | 583 std::vector<std::string>* excluded_out) { |
| 547 AutoLock lock(lock_); | 584 AutoLock lock(lock_); |
| 548 if (enable_count_) { | 585 if (enable_count_) { |
| 549 *included_out = included_categories_; | 586 *included_out = included_categories_; |
| 550 *excluded_out = excluded_categories_; | 587 *excluded_out = excluded_categories_; |
| 551 } | 588 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 570 | 607 |
| 571 included_categories_.clear(); | 608 included_categories_.clear(); |
| 572 excluded_categories_.clear(); | 609 excluded_categories_.clear(); |
| 573 watch_category_ = NULL; | 610 watch_category_ = NULL; |
| 574 watch_event_name_ = ""; | 611 watch_event_name_ = ""; |
| 575 for (int i = 0; i < g_category_index; i++) | 612 for (int i = 0; i < g_category_index; i++) |
| 576 g_category_enabled[i] = 0; | 613 g_category_enabled[i] = 0; |
| 577 AddThreadNameMetadataEvents(); | 614 AddThreadNameMetadataEvents(); |
| 578 } | 615 } |
| 579 | 616 |
| 580 void TraceLog::SetEnabled(bool enabled) { | 617 void TraceLog::SetEnabled(bool enabled, Options options) { |
| 581 if (enabled) | 618 if (enabled) |
| 582 SetEnabled(std::vector<std::string>(), std::vector<std::string>()); | 619 SetEnabled(std::vector<std::string>(), std::vector<std::string>(), options); |
| 583 else | 620 else |
| 584 SetDisabled(); | 621 SetDisabled(); |
| 585 } | 622 } |
| 586 | 623 |
| 587 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { | 624 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { |
| 588 enabled_state_observer_list_.AddObserver(listener); | 625 enabled_state_observer_list_.AddObserver(listener); |
| 589 } | 626 } |
| 590 | 627 |
| 591 void TraceLog::RemoveEnabledStateObserver( | 628 void TraceLog::RemoveEnabledStateObserver( |
| 592 EnabledStateChangedObserver* listener) { | 629 EnabledStateChangedObserver* listener) { |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 0, // num_args | 899 0, // num_args |
| 863 NULL, // arg_names | 900 NULL, // arg_names |
| 864 NULL, // arg_types | 901 NULL, // arg_types |
| 865 NULL, // arg_values | 902 NULL, // arg_values |
| 866 TRACE_EVENT_FLAG_NONE); // flags | 903 TRACE_EVENT_FLAG_NONE); // flags |
| 867 } | 904 } |
| 868 } | 905 } |
| 869 | 906 |
| 870 } // namespace trace_event_internal | 907 } // namespace trace_event_internal |
| 871 | 908 |
| OLD | NEW |