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 int TraceLog::TraceOptionsFromString(const std::string& options) { | |
358 std::vector<std::string> split; | |
359 std::vector<std::string>::iterator iter; | |
jar (doing other things)
2013/02/22 19:31:28
nit: move into line 363, so it is next to first us
dsinclair
2013/02/22 20:01:42
Done.
| |
360 int ret = 0; | |
361 | |
362 base::SplitString(options, ',', &split); | |
jar (doing other things)
2013/02/22 19:31:28
nit: declare closer to first use. Probably push t
dsinclair
2013/02/22 20:01:42
Done.
| |
363 for (iter = split.begin(); iter != split.end(); ++iter) { | |
364 if (*iter == kRecordUntilFull) { | |
365 ret |= RECORD_UNTIL_FULL; | |
366 } | |
jar (doing other things)
2013/02/22 19:31:28
nit: Should we have a DCHECK for other spellings h
dsinclair
2013/02/22 20:01:42
Added a else NOTREACHED();
| |
367 } | |
368 if (ret == 0) | |
369 ret = RECORD_UNTIL_FULL; | |
jar (doing other things)
2013/02/22 19:31:28
nit: Add comment: // Default when no options are s
dsinclair
2013/02/22 20:01:42
Skipping the comment as there is already a patch w
| |
370 | |
371 return ret; | |
372 } | |
373 | |
351 TraceLog::TraceLog() | 374 TraceLog::TraceLog() |
352 : enable_count_(0), | 375 : enable_count_(0), |
353 dispatching_to_observer_list_(false), | 376 dispatching_to_observer_list_(false), |
354 watch_category_(NULL) { | 377 watch_category_(NULL), |
378 trace_options_(RECORD_UNTIL_FULL) { | |
355 // Trace is enabled or disabled on one thread while other threads are | 379 // 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 | 380 // 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 | 381 // traced or not, so we allow races on the enabled flag to keep the trace |
358 // macros fast. | 382 // macros fast. |
359 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 383 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
360 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), | 384 // ANNOTATE_BENIGN_RACE_SIZED(g_category_enabled, sizeof(g_category_enabled), |
361 // "trace_event category enabled"); | 385 // "trace_event category enabled"); |
362 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { | 386 for (int i = 0; i < TRACE_EVENT_MAX_CATEGORIES; ++i) { |
363 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], | 387 ANNOTATE_BENIGN_RACE(&g_category_enabled[i], |
364 "trace_event category enabled"); | 388 "trace_event category enabled"); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 return category_enabled; | 495 return category_enabled; |
472 } | 496 } |
473 | 497 |
474 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { | 498 void TraceLog::GetKnownCategories(std::vector<std::string>* categories) { |
475 AutoLock lock(lock_); | 499 AutoLock lock(lock_); |
476 for (int i = 0; i < g_category_index; i++) | 500 for (int i = 0; i < g_category_index; i++) |
477 categories->push_back(g_categories[i]); | 501 categories->push_back(g_categories[i]); |
478 } | 502 } |
479 | 503 |
480 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, | 504 void TraceLog::SetEnabled(const std::vector<std::string>& included_categories, |
481 const std::vector<std::string>& excluded_categories) { | 505 const std::vector<std::string>& excluded_categories, |
506 int options) { | |
482 AutoLock lock(lock_); | 507 AutoLock lock(lock_); |
483 | 508 |
484 if (enable_count_++ > 0) { | 509 if (enable_count_++ > 0) { |
510 if (options != trace_options_) { | |
511 DLOG(ERROR) << "Attemting to re-enable tracing with a different " | |
512 << "set of options."; | |
513 } | |
514 | |
485 // Tracing is already enabled, so just merge in enabled categories. | 515 // Tracing is already enabled, so just merge in enabled categories. |
486 // We only expand the set of enabled categories upon nested SetEnable(). | 516 // We only expand the set of enabled categories upon nested SetEnable(). |
487 if (!included_categories_.empty() && !included_categories.empty()) { | 517 if (!included_categories_.empty() && !included_categories.empty()) { |
488 included_categories_.insert(included_categories_.end(), | 518 included_categories_.insert(included_categories_.end(), |
489 included_categories.begin(), | 519 included_categories.begin(), |
490 included_categories.end()); | 520 included_categories.end()); |
491 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 521 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); |
492 } else { | 522 } else { |
493 // If either old or new included categories are empty, allow all events. | 523 // If either old or new included categories are empty, allow all events. |
494 included_categories_.clear(); | 524 included_categories_.clear(); |
495 excluded_categories_.clear(); | 525 excluded_categories_.clear(); |
496 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 526 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); |
497 } | 527 } |
498 return; | 528 return; |
499 } | 529 } |
530 trace_options_ = options; | |
500 | 531 |
501 if (dispatching_to_observer_list_) { | 532 if (dispatching_to_observer_list_) { |
502 DLOG(ERROR) << | 533 DLOG(ERROR) << |
503 "Cannot manipulate TraceLog::Enabled state from an observer."; | 534 "Cannot manipulate TraceLog::Enabled state from an observer."; |
504 return; | 535 return; |
505 } | 536 } |
506 | 537 |
507 dispatching_to_observer_list_ = true; | 538 dispatching_to_observer_list_ = true; |
508 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, | 539 FOR_EACH_OBSERVER(EnabledStateChangedObserver, enabled_state_observer_list_, |
509 OnTraceLogWillEnable()); | 540 OnTraceLogWillEnable()); |
510 dispatching_to_observer_list_ = false; | 541 dispatching_to_observer_list_ = false; |
511 | 542 |
512 logged_events_.reserve(1024); | 543 logged_events_.reserve(1024); |
513 included_categories_ = included_categories; | 544 included_categories_ = included_categories; |
514 excluded_categories_ = excluded_categories; | 545 excluded_categories_ = excluded_categories; |
515 // Note that if both included and excluded_categories are empty, the else | 546 // Note that if both included and excluded_categories are empty, the else |
516 // clause below excludes nothing, thereby enabling all categories. | 547 // clause below excludes nothing, thereby enabling all categories. |
517 if (!included_categories_.empty()) | 548 if (!included_categories_.empty()) |
518 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); | 549 EnableMatchingCategories(included_categories_, CATEGORY_ENABLED, 0); |
519 else | 550 else |
520 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); | 551 EnableMatchingCategories(excluded_categories_, 0, CATEGORY_ENABLED); |
521 } | 552 } |
522 | 553 |
523 void TraceLog::SetEnabled(const std::string& categories) { | 554 void TraceLog::SetEnabled(const std::string& categories, int options) { |
524 std::vector<std::string> included, excluded; | 555 std::vector<std::string> included, excluded; |
525 // Tokenize list of categories, delimited by ','. | 556 // Tokenize list of categories, delimited by ','. |
526 StringTokenizer tokens(categories, ","); | 557 StringTokenizer tokens(categories, ","); |
527 while (tokens.GetNext()) { | 558 while (tokens.GetNext()) { |
528 bool is_included = true; | 559 bool is_included = true; |
529 std::string category = tokens.token(); | 560 std::string category = tokens.token(); |
530 // Excluded categories start with '-'. | 561 // Excluded categories start with '-'. |
531 if (category.at(0) == '-') { | 562 if (category.at(0) == '-') { |
532 // Remove '-' from category string. | 563 // Remove '-' from category string. |
533 category = category.substr(1); | 564 category = category.substr(1); |
534 is_included = false; | 565 is_included = false; |
535 } | 566 } |
536 if (is_included) | 567 if (is_included) |
537 included.push_back(category); | 568 included.push_back(category); |
538 else | 569 else |
539 excluded.push_back(category); | 570 excluded.push_back(category); |
540 } | 571 } |
541 SetEnabled(included, excluded); | 572 SetEnabled(included, excluded, options); |
542 } | 573 } |
543 | 574 |
544 void TraceLog::GetEnabledTraceCategories( | 575 void TraceLog::GetEnabledTraceCategories( |
545 std::vector<std::string>* included_out, | 576 std::vector<std::string>* included_out, |
546 std::vector<std::string>* excluded_out) { | 577 std::vector<std::string>* excluded_out) { |
547 AutoLock lock(lock_); | 578 AutoLock lock(lock_); |
548 if (enable_count_) { | 579 if (enable_count_) { |
549 *included_out = included_categories_; | 580 *included_out = included_categories_; |
550 *excluded_out = excluded_categories_; | 581 *excluded_out = excluded_categories_; |
551 } | 582 } |
(...skipping 18 matching lines...) Expand all Loading... | |
570 | 601 |
571 included_categories_.clear(); | 602 included_categories_.clear(); |
572 excluded_categories_.clear(); | 603 excluded_categories_.clear(); |
573 watch_category_ = NULL; | 604 watch_category_ = NULL; |
574 watch_event_name_ = ""; | 605 watch_event_name_ = ""; |
575 for (int i = 0; i < g_category_index; i++) | 606 for (int i = 0; i < g_category_index; i++) |
576 g_category_enabled[i] = 0; | 607 g_category_enabled[i] = 0; |
577 AddThreadNameMetadataEvents(); | 608 AddThreadNameMetadataEvents(); |
578 } | 609 } |
579 | 610 |
580 void TraceLog::SetEnabled(bool enabled) { | 611 void TraceLog::SetEnabled(bool enabled, int options) { |
581 if (enabled) | 612 if (enabled) |
582 SetEnabled(std::vector<std::string>(), std::vector<std::string>()); | 613 SetEnabled(std::vector<std::string>(), std::vector<std::string>(), options); |
583 else | 614 else |
584 SetDisabled(); | 615 SetDisabled(); |
585 } | 616 } |
586 | 617 |
587 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { | 618 void TraceLog::AddEnabledStateObserver(EnabledStateChangedObserver* listener) { |
588 enabled_state_observer_list_.AddObserver(listener); | 619 enabled_state_observer_list_.AddObserver(listener); |
589 } | 620 } |
590 | 621 |
591 void TraceLog::RemoveEnabledStateObserver( | 622 void TraceLog::RemoveEnabledStateObserver( |
592 EnabledStateChangedObserver* listener) { | 623 EnabledStateChangedObserver* listener) { |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
862 0, // num_args | 893 0, // num_args |
863 NULL, // arg_names | 894 NULL, // arg_names |
864 NULL, // arg_types | 895 NULL, // arg_types |
865 NULL, // arg_values | 896 NULL, // arg_values |
866 TRACE_EVENT_FLAG_NONE); // flags | 897 TRACE_EVENT_FLAG_NONE); // flags |
867 } | 898 } |
868 } | 899 } |
869 | 900 |
870 } // namespace trace_event_internal | 901 } // namespace trace_event_internal |
871 | 902 |
OLD | NEW |