| Index: base/trace_event/trace_log.cc
|
| diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
|
| index 4b21437c66114667b725e3dcfb1b70d7ea18f84b..75af14abed9e4ec38c0c4c2232c4eaed0635c474 100644
|
| --- a/base/trace_event/trace_log.cc
|
| +++ b/base/trace_event/trace_log.cc
|
| @@ -32,8 +32,11 @@
|
| #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"
|
| +#include "base/trace_event/heap_profiler_event_filter.h"
|
| #include "base/trace_event/memory_dump_manager.h"
|
| #include "base/trace_event/memory_dump_provider.h"
|
| #include "base/trace_event/process_memory_dump.h"
|
| @@ -84,83 +87,6 @@ const size_t kEchoToConsoleTraceEventBufferChunks = 256;
|
| const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
|
| const int kThreadFlushTimeoutMs = 3000;
|
|
|
| -const char kEventNameWhitelist[] = "event_name_whitelist";
|
| -
|
| -#define MAX_TRACE_EVENT_FILTERS 32
|
| -
|
| -// List of TraceEventFilter objects from the most recent tracing session.
|
| -base::LazyInstance<std::vector<std::unique_ptr<TraceLog::TraceEventFilter>>>::
|
| - Leaky g_category_group_filters = LAZY_INSTANCE_INITIALIZER;
|
| -
|
| -class EventNameFilter : public TraceLog::TraceEventFilter {
|
| - public:
|
| - EventNameFilter(const base::DictionaryValue* filter_args) {
|
| - const base::ListValue* whitelist = nullptr;
|
| - if (filter_args->GetList(kEventNameWhitelist, &whitelist)) {
|
| - for (size_t i = 0; i < whitelist->GetSize(); ++i) {
|
| - std::string event_name;
|
| - if (!whitelist->GetString(i, &event_name))
|
| - continue;
|
| -
|
| - whitelist_.insert(event_name);
|
| - }
|
| - }
|
| - }
|
| -
|
| - bool FilterTraceEvent(const TraceEvent& trace_event) const override {
|
| - return ContainsKey(whitelist_, trace_event.name());
|
| - }
|
| -
|
| - private:
|
| - std::unordered_set<std::string> whitelist_;
|
| -};
|
| -
|
| -// This filter is used to record trace events as pseudo stack for the heap
|
| -// profiler. It does not filter-out any events from the trace, ie. the behavior
|
| -// of trace events being added to TraceLog remains same: the events are added
|
| -// iff enabled for recording and not filtered-out by any other filter.
|
| -class HeapProfilerFilter : public TraceLog::TraceEventFilter {
|
| - public:
|
| - HeapProfilerFilter() {}
|
| -
|
| - bool FilterTraceEvent(const TraceEvent& trace_event) const override {
|
| - if (AllocationContextTracker::capture_mode() !=
|
| - AllocationContextTracker::CaptureMode::PSEUDO_STACK) {
|
| - return true;
|
| - }
|
| -
|
| - // TODO(primiano): Add support for events with copied name crbug.com/581079.
|
| - if (trace_event.flags() & TRACE_EVENT_FLAG_COPY)
|
| - return true;
|
| -
|
| - const char* category_name =
|
| - TraceLog::GetCategoryGroupName(trace_event.category_group_enabled());
|
| - if (trace_event.phase() == TRACE_EVENT_PHASE_BEGIN ||
|
| - trace_event.phase() == TRACE_EVENT_PHASE_COMPLETE) {
|
| - AllocationContextTracker::GetInstanceForCurrentThread()
|
| - ->PushPseudoStackFrame({category_name, trace_event.name()});
|
| - } else if (trace_event.phase() == TRACE_EVENT_PHASE_END) {
|
| - // The pop for |TRACE_EVENT_PHASE_COMPLETE| events is in |EndEvent|.
|
| - AllocationContextTracker::GetInstanceForCurrentThread()
|
| - ->PopPseudoStackFrame({category_name, trace_event.name()});
|
| - }
|
| - // Do not filter-out any events and always return true. TraceLog adds the
|
| - // event only if it is enabled for recording.
|
| - return true;
|
| - }
|
| -
|
| - void EndEvent(const char* name, const char* category_group) override {
|
| - if (AllocationContextTracker::capture_mode() ==
|
| - AllocationContextTracker::CaptureMode::PSEUDO_STACK) {
|
| - AllocationContextTracker::GetInstanceForCurrentThread()
|
| - ->PopPseudoStackFrame({category_group, name});
|
| - }
|
| - }
|
| -};
|
| -
|
| -TraceLog::TraceEventFilterConstructorForTesting
|
| - g_trace_event_filter_constructor_for_testing = nullptr;
|
| -
|
| // 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.
|
| @@ -232,17 +158,13 @@ void MakeHandle(uint32_t chunk_seq,
|
| }
|
|
|
| template <typename Function>
|
| -void ForEachCategoryGroupFilter(const unsigned char* category_group_enabled,
|
| - Function filter_fn) {
|
| - const TraceCategory* category =
|
| - CategoryRegistry::GetCategoryByStatePtr(category_group_enabled);
|
| - uint32_t filter_bitmap = category->enabled_filters();
|
| - int index = 0;
|
| - while (filter_bitmap) {
|
| - if (filter_bitmap & 1 && g_category_group_filters.Get()[index])
|
| - filter_fn(g_category_group_filters.Get()[index].get());
|
| - filter_bitmap = filter_bitmap >> 1;
|
| - index++;
|
| +void ForEachCategoryFilter(const unsigned char* category_group_enabled,
|
| + Function filter_fn) {
|
| + auto* cat = CategoryRegistry::GetCategoryByStatePtr(category_group_enabled);
|
| + uint32_t filter_bitmap = cat->enabled_filters();
|
| + for (int index = 0; filter_bitmap != 0; filter_bitmap >>= 1, index++) {
|
| + if (filter_bitmap & 1)
|
| + filter_fn(EventFilterRegistry::Get(index));
|
| }
|
| }
|
|
|
| @@ -539,16 +461,16 @@ 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 (const auto& filter_config : enabled_event_filters_) {
|
| + if (filter_config.IsCategoryGroupEnabled(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;
|
| + const int filter_index = EventFilterRegistry::GetIndexByName(
|
| + filter_config.predicate_name().c_str());
|
| + if (filter_index == -1) {
|
| + NOTREACHED();
|
| + continue;
|
| + }
|
| + enabled_filters_bitmap |= 1ul << filter_index;
|
| }
|
| }
|
| category->set_enabled_filters(enabled_filters_bitmap);
|
| @@ -563,35 +485,35 @@ void TraceLog::UpdateCategoryRegistry() {
|
| }
|
|
|
| void TraceLog::CreateFiltersForTraceConfig() {
|
| - if (!(enabled_modes_ & FILTERING_MODE))
|
| - return;
|
| + lock_.AssertAcquired();
|
|
|
| - // 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())
|
| + if (!(enabled_modes_ & FILTERING_MODE))
|
| return;
|
|
|
| + // |enabled_event_filters_| is the TraceConfig's filter list at the time
|
| + // tracing was started (?).
|
| for (auto& event_filter : 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;
|
| - }
|
| -
|
| std::unique_ptr<TraceEventFilter> new_filter;
|
| - if (event_filter.predicate_name() ==
|
| - TraceEventFilter::kEventWhitelistPredicate) {
|
| - new_filter = MakeUnique<EventNameFilter>(event_filter.filter_args());
|
| + if (event_filter.predicate_name() == EventNameFilter::kName) {
|
| + auto* flt = EventFilterRegistry::RegisterFilterLocked<EventNameFilter>();
|
| + auto whitelist = MakeUnique<std::unordered_set<std::string>>();
|
| + const ListValue* list = nullptr;
|
| + if (event_filter.filter_args()->GetList("event_name_whitelist", &list)) {
|
| + for (size_t i = 0; i < list->GetSize(); ++i) {
|
| + std::string event_name;
|
| + if (list->GetString(i, &event_name))
|
| + whitelist->insert(event_name);
|
| + }
|
| + }
|
| + flt->SetWhitelistedEventNames(std::move(whitelist));
|
| } else if (event_filter.predicate_name() ==
|
| - TraceEventFilter::kHeapProfilerPredicate) {
|
| - new_filter = MakeUnique<HeapProfilerFilter>();
|
| - } else if (event_filter.predicate_name() == "testing_predicate") {
|
| - CHECK(g_trace_event_filter_constructor_for_testing);
|
| - new_filter = g_trace_event_filter_constructor_for_testing();
|
| + HeapProfilerEventFilter::kName) {
|
| + EventFilterRegistry::RegisterFilterLocked<HeapProfilerEventFilter>();
|
| } else {
|
| - NOTREACHED();
|
| + // Check that the filter has been already registered externally.
|
| + DCHECK(EventFilterRegistry::GetByName(
|
| + event_filter.predicate_name().c_str()));
|
| }
|
| - g_category_group_filters.Get().push_back(std::move(new_filter));
|
| }
|
| }
|
|
|
| @@ -654,12 +576,6 @@ 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;
|
| if (modes_to_enable & RECORDING_MODE) {
|
| @@ -1338,7 +1254,7 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
|
| arg_values, convertable_values, flags);
|
|
|
| disabled_by_filters = true;
|
| - ForEachCategoryGroupFilter(
|
| + ForEachCategoryFilter(
|
| category_group_enabled, [&new_trace_event, &disabled_by_filters](
|
| TraceEventFilter* trace_event_filter) {
|
| if (trace_event_filter->FilterTraceEvent(*new_trace_event))
|
| @@ -1468,10 +1384,10 @@ void TraceLog::EndFilteredEvent(const unsigned char* category_group_enabled,
|
| const char* name,
|
| TraceEventHandle handle) {
|
| const char* category_name = GetCategoryGroupName(category_group_enabled);
|
| - ForEachCategoryGroupFilter(
|
| + ForEachCategoryFilter(
|
| category_group_enabled,
|
| [name, category_name](TraceEventFilter* trace_event_filter) {
|
| - trace_event_filter->EndEvent(name, category_name);
|
| + trace_event_filter->EndEvent(category_name, name);
|
| });
|
| }
|
|
|
| @@ -1612,11 +1528,6 @@ void TraceLog::DeleteForTesting() {
|
| CategoryRegistry::ResetForTesting();
|
| }
|
|
|
| -void TraceLog::SetTraceEventFilterConstructorForTesting(
|
| - TraceEventFilterConstructorForTesting predicate) {
|
| - g_trace_event_filter_constructor_for_testing = predicate;
|
| -}
|
| -
|
| TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) {
|
| return GetEventByHandleInternal(handle, NULL);
|
| }
|
|
|