Index: base/trace_event/trace_log.cc |
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc |
index edfd6488bb5c35a7afb48025d3fb0b4a84e4c02d..f46404fce76a6bbcbb04ae1302740d578ec53aa8 100644 |
--- a/base/trace_event/trace_log.cc |
+++ b/base/trace_event/trace_log.cc |
@@ -32,6 +32,7 @@ |
#include "base/threading/worker_pool.h" |
#include "base/time/time.h" |
#include "base/trace_event/category_registry.h" |
+#include "base/trace_event/event_filter_registry.h" |
#include "base/trace_event/event_name_filter.h" |
#include "base/trace_event/heap_profiler.h" |
#include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
@@ -86,12 +87,6 @@ const size_t kEchoToConsoleTraceEventBufferChunks = 256; |
const size_t kTraceEventBufferSizeInBytes = 100 * 1024; |
const int kThreadFlushTimeoutMs = 3000; |
-#define MAX_TRACE_EVENT_FILTERS 32 |
- |
-// List of TraceEventFilter objects from the most recent tracing session. |
-base::LazyInstance<std::vector<std::unique_ptr<TraceEventFilter>>>::Leaky |
- g_category_group_filters = LAZY_INSTANCE_INITIALIZER; |
- |
// The name of the current thread. This is used to decide if the current |
// thread name has changed. We combine all the seen thread names into the |
// output name for the thread. |
@@ -169,8 +164,8 @@ void ForEachCategoryFilter(const unsigned char* category_group_enabled, |
CategoryRegistry::GetCategoryByStatePtr(category_group_enabled); |
uint32_t filter_bitmap = category->enabled_filters(); |
for (int index = 0; filter_bitmap != 0; filter_bitmap >>= 1, index++) { |
- if (filter_bitmap & 1 && g_category_group_filters.Get()[index]) |
- filter_fn(g_category_group_filters.Get()[index].get()); |
+ if (filter_bitmap & 1) |
+ filter_fn(EventFilterRegistry::Get(index)); |
} |
} |
@@ -469,16 +464,11 @@ void TraceLog::UpdateCategoryState(TraceCategory* category) { |
#endif |
uint32_t enabled_filters_bitmap = 0; |
- int index = 0; |
- for (const auto& event_filter : enabled_event_filters_) { |
- if (event_filter.IsCategoryGroupEnabled(category->name())) { |
+ for (auto it = EventFilterRegistry::GetActiveFilters(); it.IsValid(); |
+ it.MoveNext()) { |
+ if (it->IsEnabledForCategory(category->name())) { |
state_flags |= TraceCategory::ENABLED_FOR_FILTERING; |
- DCHECK(g_category_group_filters.Get()[index]); |
- enabled_filters_bitmap |= 1 << index; |
- } |
- if (index++ >= MAX_TRACE_EVENT_FILTERS) { |
- NOTREACHED(); |
- break; |
+ enabled_filters_bitmap |= 1ul << it.GetIndex(); |
} |
} |
category->set_enabled_filters(enabled_filters_bitmap); |
@@ -487,42 +477,37 @@ void TraceLog::UpdateCategoryState(TraceCategory* category) { |
void TraceLog::UpdateCategoryRegistry() { |
lock_.AssertAcquired(); |
- CreateFiltersForTraceConfig(); |
for (TraceCategory& category : CategoryRegistry::GetAllCategories()) { |
UpdateCategoryState(&category); |
} |
} |
-void TraceLog::CreateFiltersForTraceConfig() { |
- if (!(enabled_modes_ & FILTERING_MODE)) |
- return; |
- |
- // Filters were already added and tracing could be enabled. Filters list |
- // cannot be changed when trace events are using them. |
- if (g_category_group_filters.Get().size()) |
- return; |
- |
- for (auto& filter_config : enabled_event_filters_) { |
- if (g_category_group_filters.Get().size() >= MAX_TRACE_EVENT_FILTERS) { |
- NOTREACHED() |
- << "Too many trace event filters installed in the current session"; |
- break; |
- } |
+void TraceLog::CreateFiltersAndUpdateFilterRegistry() { |
+ // At this point all existing filters should have been unregistered. |
+ DCHECK(!EventFilterRegistry::GetActiveFilters().IsValid()); |
+ for (const auto& filter_config : trace_config_.event_filters()) { |
+ // Create a copy of the filter config and pass it to the newly created |
+ // filter instance. This allows to check whether a given category should |
+ // be filtered without having to keep additional state here in the TraceLog. |
+ std::unique_ptr<TraceEventFilter::Config> base_filter_config( |
+ new TraceConfig::EventFilterConfig(filter_config)); |
std::unique_ptr<TraceEventFilter> new_filter; |
const std::string& predicate_name = filter_config.predicate_name(); |
if (predicate_name == EventNameFilter::kName) { |
auto whitelist = MakeUnique<std::unordered_set<std::string>>(); |
CHECK(filter_config.GetArgAsSet("event_name_whitelist", &*whitelist)); |
- new_filter = MakeUnique<EventNameFilter>(std::move(whitelist)); |
+ new_filter = MakeUnique<EventNameFilter>(std::move(base_filter_config), |
+ std::move(whitelist)); |
} else if (predicate_name == HeapProfilerEventFilter::kName) { |
- new_filter = MakeUnique<HeapProfilerEventFilter>(); |
- } else { |
- if (filter_factory_for_testing_) |
- new_filter = filter_factory_for_testing_(predicate_name); |
- CHECK(new_filter) << "Unknown trace filter " << predicate_name; |
+ new_filter = |
+ MakeUnique<HeapProfilerEventFilter>(std::move(base_filter_config)); |
+ } else if (filter_factory_for_testing_) { |
+ new_filter = filter_factory_for_testing_(predicate_name, |
+ std::move(base_filter_config)); |
} |
- g_category_group_filters.Get().push_back(std::move(new_filter)); |
+ CHECK(new_filter) << "Unknown trace filter " << predicate_name; |
+ EventFilterRegistry::RegisterFilter(std::move(new_filter)); |
} |
} |
@@ -585,15 +570,19 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config, |
return; |
} |
- // Clear all filters from previous tracing session. These filters are not |
- // cleared at the end of tracing because some threads which hit trace event |
- // when disabling, could try to use the filters. |
- if (!enabled_modes_) |
- g_category_group_filters.Get().clear(); |
- |
// Update trace config for recording. |
- const bool already_recording = enabled_modes_ & RECORDING_MODE; |
+ const bool already_recording = (enabled_modes_ & RECORDING_MODE) != 0; |
if (modes_to_enable & RECORDING_MODE) { |
+ // Save the current filter config (and restore below) in order to prevent |
+ // clobbering the filter section of the TraceConfig when enabling only |
+ // the recording mode. This is to ensure that GetCurrentTraceConfig() |
+ // always returns a consistent snapshot of the current state. |
+ 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
|
+ if (!(modes_to_enable & FILTERING_MODE)) { |
+ saved_filters_config.reset( |
+ new TraceConfig::EventFilters(trace_config_.event_filters())); |
+ } |
+ |
if (already_recording) { |
// TODO(ssid): Stop suporting enabling of RECODING_MODE when already |
// enabled crbug.com/625170. |
@@ -604,24 +593,24 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config, |
} else { |
trace_config_ = trace_config; |
} |
+ |
+ if (saved_filters_config) |
+ trace_config_.SetEventFilters(*saved_filters_config); |
} |
// Update event filters. |
if (modes_to_enable & FILTERING_MODE) { |
- DCHECK(!trace_config.event_filters().empty()) |
- << "Attempting to enable filtering without any filters"; |
- DCHECK(enabled_event_filters_.empty()) << "Attempting to re-enable " |
- "filtering when filters are " |
- "already enabled."; |
- |
- // Use the given event filters only if filtering was not enabled. |
- if (enabled_event_filters_.empty()) |
- enabled_event_filters_ = trace_config.event_filters(); |
+ const bool already_filtering = (enabled_modes_ & FILTERING_MODE) != 0; |
+ CHECK(!already_filtering) << "Attempting to re-enable filtering"; |
+ CHECK(!trace_config.event_filters().empty()) |
+ << "Attempting to enable filtering with an empty filter set"; |
+ trace_config_.SetEventFilters(trace_config.event_filters()); |
+ CreateFiltersAndUpdateFilterRegistry(); |
+ } else { |
+ CHECK(trace_config.event_filters().empty()) |
ssid
2016/12/12 04:50:18
Crashes in case of --enable-heap-profiling:
Tracin
|
+ << "The trace config is specifying some filters but tracing is not " |
+ "being enabled for FILTERING_MODE."; |
} |
- // Keep the |trace_config_| updated with only enabled filters in case anyone |
- // tries to read it using |GetCurrentTraceConfig| (even if filters are |
- // empty). |
- trace_config_.SetEventFilters(enabled_event_filters_); |
enabled_modes_ |= modes_to_enable; |
UpdateCategoryRegistry(); |
@@ -720,7 +709,7 @@ void TraceLog::SetDisabledWhileLocked(uint8_t modes_to_disable) { |
enabled_modes_ &= ~modes_to_disable; |
if (modes_to_disable & FILTERING_MODE) |
- enabled_event_filters_.clear(); |
+ EventFilterRegistry::UnregisterAllFilters(); |
if (modes_to_disable & RECORDING_MODE) |
trace_config_.Clear(); |