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); |
} |