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

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

Issue 2557743002: tracing: simplify lifetime of TraceEventFilter(s) (Closed)
Patch Set: rebase Created 4 years 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_log.h" 5 #include "base/trace_event/trace_log.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
(...skipping 14 matching lines...) Expand all
25 #include "base/strings/string_split.h" 25 #include "base/strings/string_split.h"
26 #include "base/strings/string_tokenizer.h" 26 #include "base/strings/string_tokenizer.h"
27 #include "base/strings/stringprintf.h" 27 #include "base/strings/stringprintf.h"
28 #include "base/sys_info.h" 28 #include "base/sys_info.h"
29 #include "base/threading/platform_thread.h" 29 #include "base/threading/platform_thread.h"
30 #include "base/threading/thread_id_name_manager.h" 30 #include "base/threading/thread_id_name_manager.h"
31 #include "base/threading/thread_task_runner_handle.h" 31 #include "base/threading/thread_task_runner_handle.h"
32 #include "base/threading/worker_pool.h" 32 #include "base/threading/worker_pool.h"
33 #include "base/time/time.h" 33 #include "base/time/time.h"
34 #include "base/trace_event/category_registry.h" 34 #include "base/trace_event/category_registry.h"
35 #include "base/trace_event/event_filter_registry.h"
35 #include "base/trace_event/event_name_filter.h" 36 #include "base/trace_event/event_name_filter.h"
36 #include "base/trace_event/heap_profiler.h" 37 #include "base/trace_event/heap_profiler.h"
37 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" 38 #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
38 #include "base/trace_event/heap_profiler_event_filter.h" 39 #include "base/trace_event/heap_profiler_event_filter.h"
39 #include "base/trace_event/memory_dump_manager.h" 40 #include "base/trace_event/memory_dump_manager.h"
40 #include "base/trace_event/memory_dump_provider.h" 41 #include "base/trace_event/memory_dump_provider.h"
41 #include "base/trace_event/process_memory_dump.h" 42 #include "base/trace_event/process_memory_dump.h"
42 #include "base/trace_event/trace_buffer.h" 43 #include "base/trace_event/trace_buffer.h"
43 #include "base/trace_event/trace_event.h" 44 #include "base/trace_event/trace_event.h"
44 #include "base/trace_event/trace_event_synthetic_delay.h" 45 #include "base/trace_event/trace_event_synthetic_delay.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 kTraceEventVectorBufferChunks <= TraceBufferChunk::kMaxChunkIndex, 80 kTraceEventVectorBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
80 "Too many vector buffer chunks"); 81 "Too many vector buffer chunks");
81 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; 82 const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4;
82 83
83 // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events. 84 // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events.
84 const size_t kEchoToConsoleTraceEventBufferChunks = 256; 85 const size_t kEchoToConsoleTraceEventBufferChunks = 256;
85 86
86 const size_t kTraceEventBufferSizeInBytes = 100 * 1024; 87 const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
87 const int kThreadFlushTimeoutMs = 3000; 88 const int kThreadFlushTimeoutMs = 3000;
88 89
89 #define MAX_TRACE_EVENT_FILTERS 32
90
91 // List of TraceEventFilter objects from the most recent tracing session.
92 base::LazyInstance<std::vector<std::unique_ptr<TraceEventFilter>>>::Leaky
93 g_category_group_filters = LAZY_INSTANCE_INITIALIZER;
94
95 // The name of the current thread. This is used to decide if the current 90 // The name of the current thread. This is used to decide if the current
96 // thread name has changed. We combine all the seen thread names into the 91 // thread name has changed. We combine all the seen thread names into the
97 // output name for the thread. 92 // output name for the thread.
98 LazyInstance<ThreadLocalPointer<const char>>::Leaky g_current_thread_name = 93 LazyInstance<ThreadLocalPointer<const char>>::Leaky g_current_thread_name =
99 LAZY_INSTANCE_INITIALIZER; 94 LAZY_INSTANCE_INITIALIZER;
100 95
101 ThreadTicks ThreadNow() { 96 ThreadTicks ThreadNow() {
102 return ThreadTicks::IsSupported() ? ThreadTicks::Now() : ThreadTicks(); 97 return ThreadTicks::IsSupported() ? ThreadTicks::Now() : ThreadTicks();
103 } 98 }
104 99
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 handle->event_index = static_cast<uint16_t>(event_index); 157 handle->event_index = static_cast<uint16_t>(event_index);
163 } 158 }
164 159
165 template <typename Function> 160 template <typename Function>
166 void ForEachCategoryFilter(const unsigned char* category_group_enabled, 161 void ForEachCategoryFilter(const unsigned char* category_group_enabled,
167 Function filter_fn) { 162 Function filter_fn) {
168 const TraceCategory* category = 163 const TraceCategory* category =
169 CategoryRegistry::GetCategoryByStatePtr(category_group_enabled); 164 CategoryRegistry::GetCategoryByStatePtr(category_group_enabled);
170 uint32_t filter_bitmap = category->enabled_filters(); 165 uint32_t filter_bitmap = category->enabled_filters();
171 for (int index = 0; filter_bitmap != 0; filter_bitmap >>= 1, index++) { 166 for (int index = 0; filter_bitmap != 0; filter_bitmap >>= 1, index++) {
172 if (filter_bitmap & 1 && g_category_group_filters.Get()[index]) 167 if (filter_bitmap & 1)
173 filter_fn(g_category_group_filters.Get()[index].get()); 168 filter_fn(EventFilterRegistry::Get(index));
174 } 169 }
175 } 170 }
176 171
177 } // namespace 172 } // namespace
178 173
179 // A helper class that allows the lock to be acquired in the middle of the scope 174 // A helper class that allows the lock to be acquired in the middle of the scope
180 // and unlocks at the end of scope if locked. 175 // and unlocks at the end of scope if locked.
181 class TraceLog::OptionalAutoLock { 176 class TraceLog::OptionalAutoLock {
182 public: 177 public:
183 explicit OptionalAutoLock(Lock* lock) : lock_(lock), locked_(false) {} 178 explicit OptionalAutoLock(Lock* lock) : lock_(lock), locked_(false) {}
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 } 457 }
463 458
464 #if defined(OS_WIN) 459 #if defined(OS_WIN)
465 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled( 460 if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
466 category->name())) { 461 category->name())) {
467 state_flags |= TraceCategory::ENABLED_FOR_ETW_EXPORT; 462 state_flags |= TraceCategory::ENABLED_FOR_ETW_EXPORT;
468 } 463 }
469 #endif 464 #endif
470 465
471 uint32_t enabled_filters_bitmap = 0; 466 uint32_t enabled_filters_bitmap = 0;
472 int index = 0; 467 for (auto it = EventFilterRegistry::GetActiveFilters(); it.IsValid();
473 for (const auto& event_filter : enabled_event_filters_) { 468 it.MoveNext()) {
474 if (event_filter.IsCategoryGroupEnabled(category->name())) { 469 if (it->IsEnabledForCategory(category->name())) {
475 state_flags |= TraceCategory::ENABLED_FOR_FILTERING; 470 state_flags |= TraceCategory::ENABLED_FOR_FILTERING;
476 DCHECK(g_category_group_filters.Get()[index]); 471 enabled_filters_bitmap |= 1ul << it.GetIndex();
477 enabled_filters_bitmap |= 1 << index;
478 }
479 if (index++ >= MAX_TRACE_EVENT_FILTERS) {
480 NOTREACHED();
481 break;
482 } 472 }
483 } 473 }
484 category->set_enabled_filters(enabled_filters_bitmap); 474 category->set_enabled_filters(enabled_filters_bitmap);
485 category->set_state(state_flags); 475 category->set_state(state_flags);
486 } 476 }
487 477
488 void TraceLog::UpdateCategoryRegistry() { 478 void TraceLog::UpdateCategoryRegistry() {
489 lock_.AssertAcquired(); 479 lock_.AssertAcquired();
490 CreateFiltersForTraceConfig();
491 for (TraceCategory& category : CategoryRegistry::GetAllCategories()) { 480 for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
492 UpdateCategoryState(&category); 481 UpdateCategoryState(&category);
493 } 482 }
494 } 483 }
495 484
496 void TraceLog::CreateFiltersForTraceConfig() { 485 void TraceLog::CreateFiltersAndUpdateFilterRegistry() {
497 if (!(enabled_modes_ & FILTERING_MODE)) 486 // At this point all existing filters should have been unregistered.
498 return; 487 DCHECK(!EventFilterRegistry::GetActiveFilters().IsValid());
499 488
500 // Filters were already added and tracing could be enabled. Filters list 489 for (const auto& filter_config : trace_config_.event_filters()) {
501 // cannot be changed when trace events are using them. 490 // Create a copy of the filter config and pass it to the newly created
502 if (g_category_group_filters.Get().size()) 491 // filter instance. This allows to check whether a given category should
503 return; 492 // be filtered without having to keep additional state here in the TraceLog.
504 493 std::unique_ptr<TraceEventFilter::Config> base_filter_config(
505 for (auto& filter_config : enabled_event_filters_) { 494 new TraceConfig::EventFilterConfig(filter_config));
506 if (g_category_group_filters.Get().size() >= MAX_TRACE_EVENT_FILTERS) {
507 NOTREACHED()
508 << "Too many trace event filters installed in the current session";
509 break;
510 }
511
512 std::unique_ptr<TraceEventFilter> new_filter; 495 std::unique_ptr<TraceEventFilter> new_filter;
513 const std::string& predicate_name = filter_config.predicate_name(); 496 const std::string& predicate_name = filter_config.predicate_name();
514 if (predicate_name == EventNameFilter::kName) { 497 if (predicate_name == EventNameFilter::kName) {
515 auto whitelist = MakeUnique<std::unordered_set<std::string>>(); 498 auto whitelist = MakeUnique<std::unordered_set<std::string>>();
516 CHECK(filter_config.GetArgAsSet("event_name_whitelist", &*whitelist)); 499 CHECK(filter_config.GetArgAsSet("event_name_whitelist", &*whitelist));
517 new_filter = MakeUnique<EventNameFilter>(std::move(whitelist)); 500 new_filter = MakeUnique<EventNameFilter>(std::move(base_filter_config),
501 std::move(whitelist));
518 } else if (predicate_name == HeapProfilerEventFilter::kName) { 502 } else if (predicate_name == HeapProfilerEventFilter::kName) {
519 new_filter = MakeUnique<HeapProfilerEventFilter>(); 503 new_filter =
520 } else { 504 MakeUnique<HeapProfilerEventFilter>(std::move(base_filter_config));
521 if (filter_factory_for_testing_) 505 } else if (filter_factory_for_testing_) {
522 new_filter = filter_factory_for_testing_(predicate_name); 506 new_filter = filter_factory_for_testing_(predicate_name,
523 CHECK(new_filter) << "Unknown trace filter " << predicate_name; 507 std::move(base_filter_config));
524 } 508 }
525 g_category_group_filters.Get().push_back(std::move(new_filter)); 509 CHECK(new_filter) << "Unknown trace filter " << predicate_name;
510 EventFilterRegistry::RegisterFilter(std::move(new_filter));
526 } 511 }
527 } 512 }
528 513
529 void TraceLog::UpdateSyntheticDelaysFromTraceConfig() { 514 void TraceLog::UpdateSyntheticDelaysFromTraceConfig() {
530 ResetTraceEventSyntheticDelays(); 515 ResetTraceEventSyntheticDelays();
531 const TraceConfig::StringList& delays = 516 const TraceConfig::StringList& delays =
532 trace_config_.GetSyntheticDelayValues(); 517 trace_config_.GetSyntheticDelayValues();
533 TraceConfig::StringList::const_iterator ci; 518 TraceConfig::StringList::const_iterator ci;
534 for (ci = delays.begin(); ci != delays.end(); ++ci) { 519 for (ci = delays.begin(); ci != delays.end(); ++ci) {
535 StringTokenizer tokens(*ci, ";"); 520 StringTokenizer tokens(*ci, ";");
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 563
579 InternalTraceOptions old_options = trace_options(); 564 InternalTraceOptions old_options = trace_options();
580 565
581 if (dispatching_to_observer_list_) { 566 if (dispatching_to_observer_list_) {
582 // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170. 567 // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
583 DLOG(ERROR) 568 DLOG(ERROR)
584 << "Cannot manipulate TraceLog::Enabled state from an observer."; 569 << "Cannot manipulate TraceLog::Enabled state from an observer.";
585 return; 570 return;
586 } 571 }
587 572
588 // Clear all filters from previous tracing session. These filters are not 573 // Update trace config for recording.
589 // cleared at the end of tracing because some threads which hit trace event 574 const bool already_recording = (enabled_modes_ & RECORDING_MODE) != 0;
590 // when disabling, could try to use the filters. 575 if (modes_to_enable & RECORDING_MODE) {
591 if (!enabled_modes_) 576 // Save the current filter config (and restore below) in order to prevent
592 g_category_group_filters.Get().clear(); 577 // clobbering the filter section of the TraceConfig when enabling only
578 // the recording mode. This is to ensure that GetCurrentTraceConfig()
579 // always returns a consistent snapshot of the current state.
580 std::unique_ptr<TraceConfig::EventFilters> saved_filters_config;
ssid 2016/12/12 04:50:18 I do not think this is required anymore. The Trace
581 if (!(modes_to_enable & FILTERING_MODE)) {
582 saved_filters_config.reset(
583 new TraceConfig::EventFilters(trace_config_.event_filters()));
584 }
593 585
594 // Update trace config for recording.
595 const bool already_recording = enabled_modes_ & RECORDING_MODE;
596 if (modes_to_enable & RECORDING_MODE) {
597 if (already_recording) { 586 if (already_recording) {
598 // TODO(ssid): Stop suporting enabling of RECODING_MODE when already 587 // TODO(ssid): Stop suporting enabling of RECODING_MODE when already
599 // enabled crbug.com/625170. 588 // enabled crbug.com/625170.
600 DCHECK_EQ(new_options, old_options) << "Attempting to re-enable " 589 DCHECK_EQ(new_options, old_options) << "Attempting to re-enable "
601 "tracing with a different set " 590 "tracing with a different set "
602 "of options."; 591 "of options.";
603 trace_config_.Merge(trace_config); 592 trace_config_.Merge(trace_config);
604 } else { 593 } else {
605 trace_config_ = trace_config; 594 trace_config_ = trace_config;
606 } 595 }
596
597 if (saved_filters_config)
598 trace_config_.SetEventFilters(*saved_filters_config);
607 } 599 }
608 600
609 // Update event filters. 601 // Update event filters.
610 if (modes_to_enable & FILTERING_MODE) { 602 if (modes_to_enable & FILTERING_MODE) {
611 DCHECK(!trace_config.event_filters().empty()) 603 const bool already_filtering = (enabled_modes_ & FILTERING_MODE) != 0;
612 << "Attempting to enable filtering without any filters"; 604 CHECK(!already_filtering) << "Attempting to re-enable filtering";
613 DCHECK(enabled_event_filters_.empty()) << "Attempting to re-enable " 605 CHECK(!trace_config.event_filters().empty())
614 "filtering when filters are " 606 << "Attempting to enable filtering with an empty filter set";
615 "already enabled."; 607 trace_config_.SetEventFilters(trace_config.event_filters());
616 608 CreateFiltersAndUpdateFilterRegistry();
617 // Use the given event filters only if filtering was not enabled. 609 } else {
618 if (enabled_event_filters_.empty()) 610 CHECK(trace_config.event_filters().empty())
ssid 2016/12/12 04:50:18 Crashes in case of --enable-heap-profiling: Tracin
619 enabled_event_filters_ = trace_config.event_filters(); 611 << "The trace config is specifying some filters but tracing is not "
612 "being enabled for FILTERING_MODE.";
620 } 613 }
621 // Keep the |trace_config_| updated with only enabled filters in case anyone
622 // tries to read it using |GetCurrentTraceConfig| (even if filters are
623 // empty).
624 trace_config_.SetEventFilters(enabled_event_filters_);
625 614
626 enabled_modes_ |= modes_to_enable; 615 enabled_modes_ |= modes_to_enable;
627 UpdateCategoryRegistry(); 616 UpdateCategoryRegistry();
628 617
629 // Do not notify observers or create trace buffer if only enabled for 618 // Do not notify observers or create trace buffer if only enabled for
630 // filtering or if recording was already enabled. 619 // filtering or if recording was already enabled.
631 if (!(modes_to_enable & RECORDING_MODE) || already_recording) 620 if (!(modes_to_enable & RECORDING_MODE) || already_recording)
632 return; 621 return;
633 622
634 if (new_options != old_options) { 623 if (new_options != old_options) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 DLOG(ERROR) 702 DLOG(ERROR)
714 << "Cannot manipulate TraceLog::Enabled state from an observer."; 703 << "Cannot manipulate TraceLog::Enabled state from an observer.";
715 return; 704 return;
716 } 705 }
717 706
718 bool is_recording_mode_disabled = 707 bool is_recording_mode_disabled =
719 (enabled_modes_ & RECORDING_MODE) && (modes_to_disable & RECORDING_MODE); 708 (enabled_modes_ & RECORDING_MODE) && (modes_to_disable & RECORDING_MODE);
720 enabled_modes_ &= ~modes_to_disable; 709 enabled_modes_ &= ~modes_to_disable;
721 710
722 if (modes_to_disable & FILTERING_MODE) 711 if (modes_to_disable & FILTERING_MODE)
723 enabled_event_filters_.clear(); 712 EventFilterRegistry::UnregisterAllFilters();
724 713
725 if (modes_to_disable & RECORDING_MODE) 714 if (modes_to_disable & RECORDING_MODE)
726 trace_config_.Clear(); 715 trace_config_.Clear();
727 716
728 UpdateCategoryRegistry(); 717 UpdateCategoryRegistry();
729 718
730 // Add metadata events and notify observers only if recording mode was 719 // Add metadata events and notify observers only if recording mode was
731 // disabled now. 720 // disabled now.
732 if (!is_recording_mode_disabled) 721 if (!is_recording_mode_disabled)
733 return; 722 return;
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 } 1711 }
1723 1712
1724 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 1713 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
1725 if (*category_group_enabled_) { 1714 if (*category_group_enabled_) {
1726 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, 1715 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_,
1727 event_handle_); 1716 event_handle_);
1728 } 1717 }
1729 } 1718 }
1730 1719
1731 } // namespace trace_event_internal 1720 } // namespace trace_event_internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698