| OLD | NEW |
| 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 "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 private: | 74 private: |
| 75 scoped_ptr<MessageLoop> message_loop_; | 75 scoped_ptr<MessageLoop> message_loop_; |
| 76 MemoryDumpManagerDelegateForTesting delegate_; | 76 MemoryDumpManagerDelegateForTesting delegate_; |
| 77 | 77 |
| 78 // We want our singleton torn down after each test. | 78 // We want our singleton torn down after each test. |
| 79 ShadowingAtExitManager at_exit_manager_; | 79 ShadowingAtExitManager at_exit_manager_; |
| 80 }; | 80 }; |
| 81 | 81 |
| 82 class MockDumpProvider : public MemoryDumpProvider { | 82 class MockDumpProvider : public MemoryDumpProvider { |
| 83 public: | 83 public: |
| 84 MockDumpProvider() {} | 84 MockDumpProvider() : last_session_state_(nullptr) {} |
| 85 | 85 |
| 86 // Ctor used by the RespectTaskRunnerAffinity test. |
| 86 explicit MockDumpProvider( | 87 explicit MockDumpProvider( |
| 87 const scoped_refptr<SingleThreadTaskRunner>& task_runner) | 88 const scoped_refptr<SingleThreadTaskRunner>& task_runner) |
| 88 : MemoryDumpProvider(task_runner) {} | 89 : last_session_state_(nullptr), task_runner_(task_runner) {} |
| 89 | 90 |
| 90 // Ctor for the SharedSessionState test. | 91 virtual ~MockDumpProvider() {} |
| 91 explicit MockDumpProvider(const std::string& id) { | |
| 92 DeclareAllocatorAttribute("allocator" + id, "attr" + id, "type" + id); | |
| 93 } | |
| 94 | 92 |
| 95 MOCK_METHOD1(DumpInto, bool(ProcessMemoryDump* pmd)); | 93 MOCK_METHOD1(OnMemoryDump, bool(ProcessMemoryDump* pmd)); |
| 96 | 94 |
| 97 // DumpInto() override for the ActiveDumpProviderConsistency test. | 95 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. |
| 98 bool DumpIntoAndCheckDumpProviderCurrentlyActive(ProcessMemoryDump* pmd) { | 96 bool OnMemoryDump_CheckTaskRunner(ProcessMemoryDump* pmd) { |
| 99 EXPECT_EQ( | 97 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); |
| 100 this, | |
| 101 MemoryDumpManager::GetInstance()->dump_provider_currently_active()); | |
| 102 return true; | 98 return true; |
| 103 } | 99 } |
| 104 | 100 |
| 105 // DumpInto() override for the RespectTaskRunnerAffinity test. | 101 // OnMemoryDump() override for the SharedSessionState test. |
| 106 bool DumpIntoAndCheckTaskRunner(ProcessMemoryDump* pmd) { | 102 bool OnMemoryDump_CheckSessionState(ProcessMemoryDump* pmd) { |
| 107 EXPECT_TRUE(task_runner()->RunsTasksOnCurrentThread()); | 103 MemoryDumpSessionState* cur_session_state = pmd->session_state().get(); |
| 104 if (last_session_state_) |
| 105 EXPECT_EQ(last_session_state_, cur_session_state); |
| 106 last_session_state_ = cur_session_state; |
| 108 return true; | 107 return true; |
| 109 } | 108 } |
| 110 | 109 |
| 111 // DumpInto() override for the SharedSessionState test. | 110 private: |
| 112 bool DumpIntoAndCheckSessionState(ProcessMemoryDump* pmd) { | 111 MemoryDumpSessionState* last_session_state_; |
| 113 EXPECT_TRUE(pmd->session_state()); | 112 scoped_refptr<SingleThreadTaskRunner> task_runner_; |
| 114 const auto& attrs_type_info = | |
| 115 pmd->session_state()->allocators_attributes_type_info; | |
| 116 EXPECT_TRUE(attrs_type_info.Exists("allocator1", "attr1")); | |
| 117 EXPECT_TRUE(attrs_type_info.Exists("allocator2", "attr2")); | |
| 118 return true; | |
| 119 } | |
| 120 | |
| 121 const char* GetFriendlyName() const override { return "MockDumpProvider"; } | |
| 122 }; | 113 }; |
| 123 | 114 |
| 124 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 115 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
| 125 MockDumpProvider mdp; | 116 MockDumpProvider mdp; |
| 126 mdm_->RegisterDumpProvider(&mdp); | 117 mdm_->RegisterDumpProvider(&mdp); |
| 127 | 118 |
| 128 // Check that the dumper is not called if the memory category is not enabled. | 119 // Check that the dumper is not called if the memory category is not enabled. |
| 129 EnableTracing("foo-and-bar-but-not-memory"); | 120 EnableTracing("foo-and-bar-but-not-memory"); |
| 130 EXPECT_CALL(mdp, DumpInto(_)).Times(0); | 121 EXPECT_CALL(mdp, OnMemoryDump(_)).Times(0); |
| 131 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 122 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 132 DisableTracing(); | 123 DisableTracing(); |
| 133 | 124 |
| 134 // Now repeat enabling the memory category and check that the dumper is | 125 // Now repeat enabling the memory category and check that the dumper is |
| 135 // invoked this time. | 126 // invoked this time. |
| 136 EnableTracing(kTraceCategory); | 127 EnableTracing(kTraceCategory); |
| 137 EXPECT_CALL(mdp, DumpInto(_)).Times(3).WillRepeatedly(Return(true)); | 128 EXPECT_CALL(mdp, OnMemoryDump(_)).Times(3).WillRepeatedly(Return(true)); |
| 138 for (int i = 0; i < 3; ++i) | 129 for (int i = 0; i < 3; ++i) |
| 139 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 130 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 140 DisableTracing(); | 131 DisableTracing(); |
| 141 | 132 |
| 142 mdm_->UnregisterDumpProvider(&mdp); | 133 mdm_->UnregisterDumpProvider(&mdp); |
| 143 | 134 |
| 144 // Finally check the unregister logic (no calls to the mdp after unregister). | 135 // Finally check the unregister logic (no calls to the mdp after unregister). |
| 145 EnableTracing(kTraceCategory); | 136 EnableTracing(kTraceCategory); |
| 146 EXPECT_CALL(mdp, DumpInto(_)).Times(0); | 137 EXPECT_CALL(mdp, OnMemoryDump(_)).Times(0); |
| 147 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 138 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 148 TraceLog::GetInstance()->SetDisabled(); | 139 TraceLog::GetInstance()->SetDisabled(); |
| 149 } | 140 } |
| 150 | 141 |
| 151 TEST_F(MemoryDumpManagerTest, SharedSessionState) { | 142 TEST_F(MemoryDumpManagerTest, SharedSessionState) { |
| 152 MockDumpProvider mdp1("1"); // Will declare an allocator property "attr1". | 143 MockDumpProvider mdp1; |
| 153 MockDumpProvider mdp2("2"); // Will declare an allocator property "attr2". | 144 MockDumpProvider mdp2; |
| 154 mdm_->RegisterDumpProvider(&mdp1); | 145 mdm_->RegisterDumpProvider(&mdp1); |
| 155 mdm_->RegisterDumpProvider(&mdp2); | 146 mdm_->RegisterDumpProvider(&mdp2); |
| 156 | 147 |
| 157 EnableTracing(kTraceCategory); | 148 EnableTracing(kTraceCategory); |
| 158 EXPECT_CALL(mdp1, DumpInto(_)).Times(2).WillRepeatedly( | 149 EXPECT_CALL(mdp1, OnMemoryDump(_)) |
| 159 Invoke(&mdp1, &MockDumpProvider::DumpIntoAndCheckSessionState)); | 150 .Times(2) |
| 160 EXPECT_CALL(mdp2, DumpInto(_)).Times(2).WillRepeatedly( | 151 .WillRepeatedly( |
| 161 Invoke(&mdp2, &MockDumpProvider::DumpIntoAndCheckSessionState)); | 152 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
| 153 EXPECT_CALL(mdp2, OnMemoryDump(_)) |
| 154 .Times(2) |
| 155 .WillRepeatedly( |
| 156 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
| 162 | 157 |
| 163 for (int i = 0; i < 2; ++i) | 158 for (int i = 0; i < 2; ++i) |
| 164 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 159 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 165 | 160 |
| 166 DisableTracing(); | 161 DisableTracing(); |
| 167 } | 162 } |
| 168 | 163 |
| 169 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { | 164 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
| 170 MockDumpProvider mdp1; | 165 MockDumpProvider mdp1; |
| 171 MockDumpProvider mdp2; | 166 MockDumpProvider mdp2; |
| 172 | 167 |
| 173 // Enable only mdp1. | 168 // Enable only mdp1. |
| 174 mdm_->RegisterDumpProvider(&mdp1); | 169 mdm_->RegisterDumpProvider(&mdp1); |
| 175 EnableTracing(kTraceCategory); | 170 EnableTracing(kTraceCategory); |
| 176 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); | 171 EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true)); |
| 177 EXPECT_CALL(mdp2, DumpInto(_)).Times(0); | 172 EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(0); |
| 178 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 173 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 179 DisableTracing(); | 174 DisableTracing(); |
| 180 | 175 |
| 181 // Invert: enable mdp1 and disable mdp2. | 176 // Invert: enable mdp1 and disable mdp2. |
| 182 mdm_->UnregisterDumpProvider(&mdp1); | 177 mdm_->UnregisterDumpProvider(&mdp1); |
| 183 mdm_->RegisterDumpProvider(&mdp2); | 178 mdm_->RegisterDumpProvider(&mdp2); |
| 184 EnableTracing(kTraceCategory); | 179 EnableTracing(kTraceCategory); |
| 185 EXPECT_CALL(mdp1, DumpInto(_)).Times(0); | 180 EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(0); |
| 186 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); | 181 EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true)); |
| 187 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 182 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 188 DisableTracing(); | 183 DisableTracing(); |
| 189 | 184 |
| 190 // Enable both mdp1 and mdp2. | 185 // Enable both mdp1 and mdp2. |
| 191 mdm_->RegisterDumpProvider(&mdp1); | 186 mdm_->RegisterDumpProvider(&mdp1); |
| 192 EnableTracing(kTraceCategory); | 187 EnableTracing(kTraceCategory); |
| 193 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); | 188 EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true)); |
| 194 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); | 189 EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true)); |
| 195 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 190 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 196 DisableTracing(); | 191 DisableTracing(); |
| 197 } | 192 } |
| 198 | 193 |
| 199 // Checks that the MemoryDumpManager respects the thread affinity when a | 194 // Checks that the MemoryDumpManager respects the thread affinity when a |
| 200 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 | 195 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 |
| 201 // threads and registering a MemoryDumpProvider on each of them. At each | 196 // threads and registering a MemoryDumpProvider on each of them. At each |
| 202 // iteration, one thread is removed, to check the live unregistration logic. | 197 // iteration, one thread is removed, to check the live unregistration logic. |
| 203 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { | 198 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { |
| 204 const uint32 kNumInitialThreads = 8; | 199 const uint32 kNumInitialThreads = 8; |
| 205 | 200 |
| 206 ScopedVector<Thread> threads; | 201 ScopedVector<Thread> threads; |
| 207 ScopedVector<MockDumpProvider> mdps; | 202 ScopedVector<MockDumpProvider> mdps; |
| 208 | 203 |
| 209 // Create the threads and setup the expectations. Given that at each iteration | 204 // Create the threads and setup the expectations. Given that at each iteration |
| 210 // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be | 205 // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be |
| 211 // invoked a number of times equal to its index. | 206 // invoked a number of times equal to its index. |
| 212 for (uint32 i = kNumInitialThreads; i > 0; --i) { | 207 for (uint32 i = kNumInitialThreads; i > 0; --i) { |
| 213 threads.push_back(new Thread("test thread")); | 208 threads.push_back(new Thread("test thread")); |
| 214 threads.back()->Start(); | 209 threads.back()->Start(); |
| 215 mdps.push_back(new MockDumpProvider(threads.back()->task_runner())); | 210 mdps.push_back(new MockDumpProvider(threads.back()->task_runner())); |
| 216 MockDumpProvider* mdp = mdps.back(); | 211 MockDumpProvider* mdp = mdps.back(); |
| 217 mdm_->RegisterDumpProvider(mdp); | 212 mdm_->RegisterDumpProvider(mdp, threads.back()->task_runner()); |
| 218 EXPECT_CALL(*mdp, DumpInto(_)) | 213 EXPECT_CALL(*mdp, OnMemoryDump(_)) |
| 219 .Times(i) | 214 .Times(i) |
| 220 .WillRepeatedly( | 215 .WillRepeatedly( |
| 221 Invoke(mdp, &MockDumpProvider::DumpIntoAndCheckTaskRunner)); | 216 Invoke(mdp, &MockDumpProvider::OnMemoryDump_CheckTaskRunner)); |
| 222 } | 217 } |
| 223 | 218 |
| 224 EnableTracing(kTraceCategory); | 219 EnableTracing(kTraceCategory); |
| 225 | 220 |
| 226 while (!threads.empty()) { | 221 while (!threads.empty()) { |
| 227 { | 222 { |
| 228 RunLoop run_loop; | 223 RunLoop run_loop; |
| 229 MemoryDumpCallback callback = | 224 MemoryDumpCallback callback = |
| 230 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 225 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
| 231 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 226 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 259 // invoked the 2nd time. | 254 // invoked the 2nd time. |
| 260 // FIXME(primiano): remove once crbug.com/461788 gets fixed. | 255 // FIXME(primiano): remove once crbug.com/461788 gets fixed. |
| 261 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { | 256 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { |
| 262 MockDumpProvider mdp1; | 257 MockDumpProvider mdp1; |
| 263 MockDumpProvider mdp2; | 258 MockDumpProvider mdp2; |
| 264 | 259 |
| 265 mdm_->RegisterDumpProvider(&mdp1); | 260 mdm_->RegisterDumpProvider(&mdp1); |
| 266 mdm_->RegisterDumpProvider(&mdp2); | 261 mdm_->RegisterDumpProvider(&mdp2); |
| 267 EnableTracing(kTraceCategory); | 262 EnableTracing(kTraceCategory); |
| 268 | 263 |
| 269 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(false)); | 264 EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(false)); |
| 270 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); | 265 EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true)); |
| 271 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 266 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 272 | 267 |
| 273 EXPECT_CALL(mdp1, DumpInto(_)).Times(0); | 268 EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(0); |
| 274 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(false)); | 269 EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(false)); |
| 275 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 270 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 276 | 271 |
| 277 DisableTracing(); | 272 DisableTracing(); |
| 278 } | 273 } |
| 279 | 274 |
| 280 // TODO(primiano): remove once crbug.com/466121 gets fixed. | |
| 281 // Ascertains that calls to MDM::dump_provider_currently_active() actually | |
| 282 // returns the MemoryDumpProvider currently active during the DumpInto() call. | |
| 283 TEST_F(MemoryDumpManagerTest, ActiveDumpProviderConsistency) { | |
| 284 MockDumpProvider mdp1; | |
| 285 MockDumpProvider mdp2; | |
| 286 | |
| 287 mdm_->RegisterDumpProvider(&mdp1); | |
| 288 mdm_->RegisterDumpProvider(&mdp2); | |
| 289 EnableTracing(kTraceCategory); | |
| 290 EXPECT_CALL(mdp1, DumpInto(_)) | |
| 291 .Times(2) | |
| 292 .WillRepeatedly(Invoke( | |
| 293 &mdp1, | |
| 294 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive)); | |
| 295 EXPECT_CALL(mdp2, DumpInto(_)) | |
| 296 .Times(2) | |
| 297 .WillRepeatedly(Invoke( | |
| 298 &mdp2, | |
| 299 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive)); | |
| 300 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | |
| 301 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | |
| 302 DisableTracing(); | |
| 303 } | |
| 304 | |
| 305 } // namespace trace_event | 275 } // namespace trace_event |
| 306 } // namespace base | 276 } // namespace base |
| OLD | NEW |