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

Unified Diff: base/trace_event/memory_dump_manager_unittest.cc

Issue 1430073002: [tracing] Allow asynchronous unregistration of unbound dump providers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: avoid repeating messages Created 4 years, 12 months 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
« no previous file with comments | « base/trace_event/memory_dump_manager.cc ('k') | base/trace_event/memory_dump_provider.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/trace_event/memory_dump_manager_unittest.cc
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 898f003807eb92ddb5f9f6a4f1865a335a5b1296..03b3afa32e5201f3239a2c41e3d0fca8414fd1ed 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -17,6 +17,7 @@
#include "base/test/test_io_thread.h"
#include "base/test/trace_event_analyzer.h"
#include "base/thread_task_runner_handle.h"
+#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/process_memory_dump.h"
@@ -93,8 +94,17 @@ class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate {
class MockMemoryDumpProvider : public MemoryDumpProvider {
public:
+ MOCK_METHOD0(Destructor, void());
MOCK_METHOD2(OnMemoryDump,
bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd));
+
+ MockMemoryDumpProvider() : enable_mock_destructor(false) {}
+ ~MockMemoryDumpProvider() override {
+ if (enable_mock_destructor)
+ Destructor();
+ }
+
+ bool enable_mock_destructor;
};
class MemoryDumpManagerTest : public testing::Test {
@@ -785,7 +795,7 @@ TEST_F(MemoryDumpManagerTest, DisableTracingWhileDumping) {
// Register also an unbound dump provider. Unbound dump providers are always
// invoked after bound ones.
MockMemoryDumpProvider unbound_mdp;
- RegisterDumpProvider(&unbound_mdp);
+ RegisterDumpProvider(&unbound_mdp, nullptr, kDefaultOptions);
EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1);
@@ -877,5 +887,72 @@ TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) {
ASSERT_EQ(events[0]->id, events[2]->id);
}
+// Tests the basics of the UnregisterAndDeleteDumpProviderSoon(): the
+// unregistration should actually delete the providers and not leak them.
+TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoon) {
+ InitializeMemoryDumpManager(false /* is_coordinator */);
+ static const int kNumProviders = 3;
+ int dtor_count = 0;
+ std::vector<scoped_ptr<MemoryDumpProvider>> mdps;
+ for (int i = 0; i < kNumProviders; ++i) {
+ scoped_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider);
+ mdp->enable_mock_destructor = true;
+ EXPECT_CALL(*mdp, Destructor())
+ .WillOnce(Invoke([&dtor_count]() { dtor_count++; }));
+ RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions);
+ mdps.push_back(std::move(mdp));
+ }
+
+ while (!mdps.empty()) {
+ mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdps.back()));
+ mdps.pop_back();
+ }
+
+ ASSERT_EQ(kNumProviders, dtor_count);
+}
+
+// This test checks against races when unregistering an unbound dump provider
+// from another thread while dumping. It registers one MDP and, when
+// OnMemoryDump() is called, it invokes UnregisterAndDeleteDumpProviderSoon()
+// from another thread. The OnMemoryDump() and the dtor call are expected to
+// happen on the same thread (the MemoryDumpManager utility thread).
+TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoonDuringDump) {
+ InitializeMemoryDumpManager(false /* is_coordinator */);
+ scoped_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider);
+ mdp->enable_mock_destructor = true;
+ RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions);
+
+ base::PlatformThreadRef thread_ref;
+ auto self_unregister_from_another_thread = [&mdp, &thread_ref](
+ const MemoryDumpArgs&, ProcessMemoryDump*) -> bool {
+ thread_ref = PlatformThread::CurrentRef();
+ TestIOThread thread_for_unregistration(TestIOThread::kAutoStart);
+ thread_for_unregistration.PostTaskAndWait(
+ FROM_HERE,
+ base::Bind(
+ &MemoryDumpManager::UnregisterAndDeleteDumpProviderSoon,
+ base::Unretained(MemoryDumpManager::GetInstance()),
+ base::Passed(scoped_ptr<MemoryDumpProvider>(std::move(mdp)))));
+ thread_for_unregistration.Stop();
+ return true;
+ };
+ EXPECT_CALL(*mdp, OnMemoryDump(_, _))
+ .Times(1)
+ .WillOnce(Invoke(self_unregister_from_another_thread));
+ EXPECT_CALL(*mdp, Destructor())
+ .Times(1)
+ .WillOnce(Invoke([&thread_ref]() {
+ EXPECT_EQ(thread_ref, PlatformThread::CurrentRef());
+ }));
+
+ EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
+ EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(2);
+ for (int i = 0; i < 2; ++i) {
+ RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+ MemoryDumpLevelOfDetail::DETAILED);
+ }
+ DisableTracing();
+}
+
} // namespace trace_event
} // namespace base
« no previous file with comments | « base/trace_event/memory_dump_manager.cc ('k') | base/trace_event/memory_dump_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698