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

Side by Side 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: fix doc Created 5 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/trace_event/memory_dump_manager.h" 5 #include "base/trace_event/memory_dump_manager.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind_helpers.h" 9 #include "base/bind_helpers.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "base/test/test_io_thread.h" 15 #include "base/test/test_io_thread.h"
16 #include "base/test/trace_event_analyzer.h" 16 #include "base/test/trace_event_analyzer.h"
17 #include "base/thread_task_runner_handle.h" 17 #include "base/thread_task_runner_handle.h"
18 #include "base/threading/platform_thread.h"
18 #include "base/threading/thread.h" 19 #include "base/threading/thread.h"
19 #include "base/trace_event/memory_dump_provider.h" 20 #include "base/trace_event/memory_dump_provider.h"
20 #include "base/trace_event/process_memory_dump.h" 21 #include "base/trace_event/process_memory_dump.h"
21 #include "base/trace_event/trace_buffer.h" 22 #include "base/trace_event/trace_buffer.h"
22 #include "base/trace_event/trace_config_memory_test_util.h" 23 #include "base/trace_event/trace_config_memory_test_util.h"
23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
25 26
26 using testing::_; 27 using testing::_;
27 using testing::AnyNumber; 28 using testing::AnyNumber;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 const MemoryDumpCallback& callback)); 85 const MemoryDumpCallback& callback));
85 86
86 uint64 GetTracingProcessId() const override { 87 uint64 GetTracingProcessId() const override {
87 NOTREACHED(); 88 NOTREACHED();
88 return MemoryDumpManager::kInvalidTracingProcessId; 89 return MemoryDumpManager::kInvalidTracingProcessId;
89 } 90 }
90 }; 91 };
91 92
92 class MockMemoryDumpProvider : public MemoryDumpProvider { 93 class MockMemoryDumpProvider : public MemoryDumpProvider {
93 public: 94 public:
95 MOCK_METHOD0(Destructor, void());
94 MOCK_METHOD2(OnMemoryDump, 96 MOCK_METHOD2(OnMemoryDump,
95 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); 97 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd));
98
99 MockMemoryDumpProvider() : enable_mock_destructor(false) {}
100 ~MockMemoryDumpProvider() override {
101 if (enable_mock_destructor)
102 Destructor();
103 }
104
105 bool enable_mock_destructor;
96 }; 106 };
97 107
98 class MemoryDumpManagerTest : public testing::Test { 108 class MemoryDumpManagerTest : public testing::Test {
99 public: 109 public:
100 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {} 110 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {}
101 111
102 void SetUp() override { 112 void SetUp() override {
103 last_callback_success_ = false; 113 last_callback_success_ = false;
104 message_loop_.reset(new MessageLoop()); 114 message_loop_.reset(new MessageLoop());
105 mdm_.reset(new MemoryDumpManager()); 115 mdm_.reset(new MemoryDumpManager());
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 878
869 ASSERT_EQ(3u, events.size()); 879 ASSERT_EQ(3u, events.size());
870 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(123))); 880 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(123)));
871 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(456))); 881 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(456)));
872 ASSERT_EQ(1u, trace_analyzer::CountMatches( 882 ASSERT_EQ(1u, trace_analyzer::CountMatches(
873 events, Query::EventPidIs(GetCurrentProcId()))); 883 events, Query::EventPidIs(GetCurrentProcId())));
874 ASSERT_EQ(events[0]->id, events[1]->id); 884 ASSERT_EQ(events[0]->id, events[1]->id);
875 ASSERT_EQ(events[0]->id, events[2]->id); 885 ASSERT_EQ(events[0]->id, events[2]->id);
876 } 886 }
877 887
888 // Tests the basics of the UnregisterAndDeleteDumpProviderAsync(): the
889 // unregistration should actually delete the providers and not leak them.
890 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderAsync) {
891 InitializeMemoryDumpManager(false /* is_coordinator */);
892 static const int kNumProviders = 3;
893 int dtor_count = 0;
894 std::vector<scoped_ptr<MemoryDumpProvider>> mdps;
895 for (int i = 0; i < kNumProviders; ++i) {
896 scoped_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider);
897 mdp->enable_mock_destructor = true;
898 EXPECT_CALL(*mdp, Destructor())
899 .WillOnce(Invoke([&dtor_count]() -> void { dtor_count++; }));
Ruud van Asseldonk 2015/12/29 11:32:46 The |-> void| part can be omitted.
Primiano Tucci (use gerrit) 2016/01/04 14:44:38 Did I already say this week that I hate C++11 lam
900 RegisterDumpProvider(mdp.get());
901 mdps.push_back(std::move(mdp));
902 }
903
904 while (!mdps.empty()) {
905 mdm_->UnregisterAndDeleteDumpProviderAsync(std::move(mdps.back()));
Ruud van Asseldonk 2015/12/29 11:32:46 So actually deletion is happening synchronously he
Primiano Tucci (use gerrit) 2016/01/04 14:44:38 Ok, Ok. I see what you mean. I renamed the method
906 mdps.pop_back();
907 }
908
909 ASSERT_EQ(kNumProviders, dtor_count);
910 }
911
912 // This test checks against races when unregistering an unbound dump provider
913 // from another thread while dumping. It register one MDP and when
ssid 2015/12/22 16:14:56 s/register/registers/
Primiano Tucci (use gerrit) 2016/01/04 14:44:38 Done.
914 // OnMemoryDump() is called, it invokes UnregisterAndDeleteDumpProviderAsync()
915 // from another thread. The OnMemoryDump() and the dtor call are expected to
916 // happen on the same thread (the MemoryDumpManager utility thread).
917 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderAsyncDuringDump) {
918 InitializeMemoryDumpManager(false /* is_coordinator */);
919 scoped_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider);
920 mdp->enable_mock_destructor = true;
921 RegisterDumpProvider(mdp.get());
922
923 base::PlatformThreadRef thread_ref;
924 auto self_unregister_from_another_thread = [&mdp, &thread_ref](
925 const MemoryDumpArgs&, ProcessMemoryDump*) -> bool {
926 thread_ref = PlatformThread::CurrentRef();
927 TestIOThread thread_for_unregistration(TestIOThread::kAutoStart);
928 thread_for_unregistration.PostTaskAndWait(
929 FROM_HERE,
930 base::Bind(
931 &MemoryDumpManager::UnregisterAndDeleteDumpProviderAsync,
932 base::Unretained(MemoryDumpManager::GetInstance()),
933 base::Passed(scoped_ptr<MemoryDumpProvider>(std::move(mdp)))));
Ruud van Asseldonk 2015/12/29 11:32:46 Why is the extra |scoped_ptr| temporary required?
Primiano Tucci (use gerrit) 2016/01/04 14:44:38 I know but this is for upcasting from scoped_ptr<M
Ruud van Asseldonk 2016/01/04 15:43:01 Ah, I see.
934 thread_for_unregistration.Stop();
935 return true;
936 };
937 EXPECT_CALL(*mdp, OnMemoryDump(_, _))
938 .Times(1)
939 .WillOnce(Invoke(self_unregister_from_another_thread));
940 EXPECT_CALL(*mdp, Destructor())
941 .Times(1)
942 .WillOnce(Invoke([&thread_ref]() -> void {
Ruud van Asseldonk 2015/12/29 11:32:46 The |-> void| part can be omitted.
Primiano Tucci (use gerrit) 2016/01/04 14:44:38 Done.
943 EXPECT_EQ(thread_ref, PlatformThread::CurrentRef());
944 }));
945
946 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
947 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(2);
948 for (int i = 0; i < 2; ++i) {
949 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
950 MemoryDumpLevelOfDetail::DETAILED);
951 }
952 DisableTracing();
953
954 // Ownership of |mdp| should have been transferred to the MemoryDumpManager at
955 // the time UnregisterAndDeleteDumpProviderAsync() was called.
956 ASSERT_FALSE(mdp);
Ruud van Asseldonk 2015/12/29 11:32:46 I would say |ASSERT_NE(nullptr, mdp.get())|, |mdp|
Primiano Tucci (use gerrit) 2016/01/04 14:44:38 I think you are right. What I am really doing here
957 }
958
878 } // namespace trace_event 959 } // namespace trace_event
879 } // namespace base 960 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698