| 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..edfd6488bb5c35a7afb48025d3fb0b4a84e4c02d 100644
|
| --- a/base/trace_event/trace_log.cc
|
| +++ b/base/trace_event/trace_log.cc
|
| @@ -32,8 +32,10 @@
|
| #include "base/threading/worker_pool.h"
|
| #include "base/time/time.h"
|
| #include "base/trace_event/category_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,82 +86,11 @@ 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;
|
| +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
|
| @@ -232,17 +163,14 @@ void MakeHandle(uint32_t chunk_seq,
|
| }
|
|
|
| template <typename Function>
|
| -void ForEachCategoryGroupFilter(const unsigned char* category_group_enabled,
|
| - Function filter_fn) {
|
| +void ForEachCategoryFilter(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) {
|
| + 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());
|
| - filter_bitmap = filter_bitmap >> 1;
|
| - index++;
|
| }
|
| }
|
|
|
| @@ -429,7 +357,8 @@ TraceLog::TraceLog()
|
| trace_config_(TraceConfig()),
|
| thread_shared_chunk_index_(0),
|
| generation_(0),
|
| - use_worker_thread_(false) {
|
| + use_worker_thread_(false),
|
| + filter_factory_for_testing_(nullptr) {
|
| CategoryRegistry::Initialize();
|
|
|
| #if defined(OS_NACL) // NaCl shouldn't expose the process id.
|
| @@ -516,6 +445,7 @@ const char* TraceLog::GetCategoryGroupName(
|
| }
|
|
|
| void TraceLog::UpdateCategoryState(TraceCategory* category) {
|
| + lock_.AssertAcquired();
|
| DCHECK(category->is_valid());
|
| unsigned char state_flags = 0;
|
| if (enabled_modes_ & RECORDING_MODE &&
|
| @@ -556,6 +486,7 @@ void TraceLog::UpdateCategoryState(TraceCategory* category) {
|
| }
|
|
|
| void TraceLog::UpdateCategoryRegistry() {
|
| + lock_.AssertAcquired();
|
| CreateFiltersForTraceConfig();
|
| for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
|
| UpdateCategoryState(&category);
|
| @@ -571,7 +502,7 @@ void TraceLog::CreateFiltersForTraceConfig() {
|
| if (g_category_group_filters.Get().size())
|
| return;
|
|
|
| - for (auto& event_filter : enabled_event_filters_) {
|
| + 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";
|
| @@ -579,17 +510,17 @@ void TraceLog::CreateFiltersForTraceConfig() {
|
| }
|
|
|
| std::unique_ptr<TraceEventFilter> new_filter;
|
| - if (event_filter.predicate_name() ==
|
| - TraceEventFilter::kEventWhitelistPredicate) {
|
| - new_filter = MakeUnique<EventNameFilter>(event_filter.filter_args());
|
| - } 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();
|
| + 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));
|
| + } else if (predicate_name == HeapProfilerEventFilter::kName) {
|
| + new_filter = MakeUnique<HeapProfilerEventFilter>();
|
| } else {
|
| - NOTREACHED();
|
| + if (filter_factory_for_testing_)
|
| + new_filter = filter_factory_for_testing_(predicate_name);
|
| + CHECK(new_filter) << "Unknown trace filter " << predicate_name;
|
| }
|
| g_category_group_filters.Get().push_back(std::move(new_filter));
|
| }
|
| @@ -791,9 +722,8 @@ void TraceLog::SetDisabledWhileLocked(uint8_t modes_to_disable) {
|
| if (modes_to_disable & FILTERING_MODE)
|
| enabled_event_filters_.clear();
|
|
|
| - if (modes_to_disable & RECORDING_MODE) {
|
| + if (modes_to_disable & RECORDING_MODE)
|
| trace_config_.Clear();
|
| - }
|
|
|
| UpdateCategoryRegistry();
|
|
|
| @@ -1338,7 +1268,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 +1398,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 +1542,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);
|
| }
|
|
|