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

Unified Diff: base/trace_event/event_filter_registry_unittest.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 side-by-side diff with in-line comments
Download patch
Index: base/trace_event/event_filter_registry_unittest.cc
diff --git a/base/trace_event/event_filter_registry_unittest.cc b/base/trace_event/event_filter_registry_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6c01571a3f22806fc5ca43f6638cda209d087b96
--- /dev/null
+++ b/base/trace_event/event_filter_registry_unittest.cc
@@ -0,0 +1,102 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/trace_event/event_filter_registry.h"
+
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "base/trace_event/trace_event_filter.h"
+#include "base/trace_event/trace_event_filter_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+namespace trace_event {
+
+class TraceEventFilterRegistryTest : public testing::Test {
+ public:
+ void SetUp() override { EventFilterRegistry::ResetForTesting(); }
+ void TearDown() override { EventFilterRegistry::ResetForTesting(); }
+
+ uint32_t GetActiveFiltersCount() {
+ uint32_t count = 0;
+ for (auto it = EventFilterRegistry::GetActiveFilters(); it.IsValid();
+ it.MoveNext(), count++) {
+ }
+ return count;
+ }
+
+ EventFilterRegistry::Iterator GetLastActiveFilter() {
+ EventFilterRegistry::Iterator it = EventFilterRegistry::GetActiveFilters();
+ uint32_t count = GetActiveFiltersCount();
+ for (uint32_t i = 1; i < count; i++)
+ it.MoveNext();
+ return it;
+ }
+};
+
+TEST_F(TraceEventFilterRegistryTest, RegistrationAndUnregistration) {
+ // Register one instance of TestEventFilter.
+ TestEventFilter* filter_ptr = new TestEventFilter(nullptr);
+ EventFilterRegistry::RegisterFilter(WrapUnique(filter_ptr));
+ ASSERT_EQ(1u, GetActiveFiltersCount());
+ ASSERT_EQ(0u, GetLastActiveFilter().GetIndex());
+ ASSERT_EQ(filter_ptr, &*GetLastActiveFilter());
+
+ // Register other 3 filters and check that the validity of the Iterator
+ // chain.
+ for (uint32_t i = 0; i < 3; i++) {
+ filter_ptr = new TestEventFilter(nullptr);
+ EventFilterRegistry::RegisterFilter(WrapUnique(filter_ptr));
+ ASSERT_EQ(i + 2, GetActiveFiltersCount());
+ ASSERT_EQ(i + 1, GetLastActiveFilter().GetIndex());
+ ASSERT_EQ(filter_ptr, &*GetLastActiveFilter());
+ }
+
+ EventFilterRegistry::UnregisterAllFilters();
+ ASSERT_EQ(0u, GetActiveFiltersCount());
+
+ for (uint32_t i = 0; i < 3; i++) {
+ filter_ptr = new TestEventFilter(nullptr);
+ EventFilterRegistry::RegisterFilter(WrapUnique(filter_ptr));
+ ASSERT_EQ(i + 1, GetActiveFiltersCount());
+ ASSERT_EQ(i + 4, GetLastActiveFilter().GetIndex());
+ ASSERT_EQ(filter_ptr, &*GetLastActiveFilter());
+ }
+}
+
+// Tests that filters are destroyed at some point in the future (i.e. not leaked
+// forever) but not immediately after unregistration (so that TRACE_EVENT macros
+// that hit filters being unregistered from another thread don't race on UAF).
+TEST_F(TraceEventFilterRegistryTest, DeferredDestruction) {
+ TestEventFilter::HitsCounter hits;
+ for (uint32_t i = 0; i < 3; i++)
+ EventFilterRegistry::RegisterFilter(MakeUnique<TestEventFilter>(nullptr));
+
+ // Check that filters are not destroyed immediately after unregistration.
+ EventFilterRegistry::UnregisterAllFilters();
+ ASSERT_EQ(0u, hits.dtor_hit_count);
+
+ // Register and unregister enough filters to run out of the circular buffer.
+ for (uint32_t i = 0; i < 256; i++) {
+ EventFilterRegistry::RegisterFilter(MakeUnique<TestEventFilter>(nullptr));
+ EventFilterRegistry::UnregisterAllFilters();
+ }
+ // A non-zero number of filters must have been desotryed at this point. The
+ // exact number depends on internal implementation details (i.e. kMaxFilter).
+ const uint32_t num_last_dtor_hits = hits.dtor_hit_count;
+ ASSERT_GT(num_last_dtor_hits, 0u);
+
+ // Register and unregister other 11 filters. Assuming that we exhausted the
+ // circular buffer above, at least 11 of the previous filters should be
+ // destroyed.
+ for (uint32_t i = 0; i < 11; i++) {
+ EventFilterRegistry::RegisterFilter(MakeUnique<TestEventFilter>(nullptr));
+ EventFilterRegistry::UnregisterAllFilters();
+ }
+ ASSERT_GE(hits.dtor_hit_count - num_last_dtor_hits, 11u);
+}
+
+} // namespace trace_event
+} // namespace base

Powered by Google App Engine
This is Rietveld 408576698