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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 base::WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 109 base::WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
110 WaitableEvent::InitialState::NOT_SIGNALED); | 110 WaitableEvent::InitialState::NOT_SIGNALED); |
111 task_runner->PostTask(from_here, std::move(task)); | 111 task_runner->PostTask(from_here, std::move(task)); |
112 task_runner->PostTask(FROM_HERE, base::BindOnce(&WaitableEvent::Signal, | 112 task_runner->PostTask(FROM_HERE, base::BindOnce(&WaitableEvent::Signal, |
113 base::Unretained(&event))); | 113 base::Unretained(&event))); |
114 // The SequencedTaskRunner guarantees that |event| will only be signaled after | 114 // The SequencedTaskRunner guarantees that |event| will only be signaled after |
115 // |task| is executed. | 115 // |task| is executed. |
116 event.Wait(); | 116 event.Wait(); |
117 } | 117 } |
118 | 118 |
119 // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback by | 119 // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback |
120 // trimming off the result argument and calling the global callback. | 120 // and keeps around the process-local result. |
121 // TODO (fmeawad): we should keep the results for verification, but currently | |
122 // all results are empty. | |
123 void ProcessDumpCallbackAdapter( | 121 void ProcessDumpCallbackAdapter( |
124 GlobalMemoryDumpCallback callback, | 122 GlobalMemoryDumpCallback callback, |
125 uint64_t dump_guid, | 123 uint64_t dump_guid, |
126 bool success, | 124 bool success, |
127 const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) { | 125 const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) { |
128 callback.Run(dump_guid, success); | 126 callback.Run(dump_guid, success); |
129 } | 127 } |
130 | 128 |
131 // This mocks the RequestGlobalDumpFunction which is typically handled by | 129 // This mocks the RequestGlobalDumpFunction which is typically handled by |
132 // process_local_dump_manager_impl.cc, by short-circuiting dump requests locally | 130 // process_local_dump_manager_impl.cc, by short-circuiting dump requests locally |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 } // namespace | 239 } // namespace |
242 | 240 |
243 class MemoryDumpManagerTest : public testing::Test { | 241 class MemoryDumpManagerTest : public testing::Test { |
244 public: | 242 public: |
245 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {} | 243 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {} |
246 | 244 |
247 void SetUp() override { | 245 void SetUp() override { |
248 last_callback_success_ = false; | 246 last_callback_success_ = false; |
249 message_loop_.reset(new MessageLoop()); | 247 message_loop_.reset(new MessageLoop()); |
250 mdm_.reset(new MemoryDumpManager()); | 248 mdm_.reset(new MemoryDumpManager()); |
| 249 results_.clear(); |
251 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); | 250 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); |
252 ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance()); | 251 ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance()); |
253 } | 252 } |
254 | 253 |
255 void TearDown() override { | 254 void TearDown() override { |
256 MemoryDumpManager::SetInstanceForTesting(nullptr); | 255 MemoryDumpManager::SetInstanceForTesting(nullptr); |
257 mdm_.reset(); | 256 mdm_.reset(); |
258 message_loop_.reset(); | 257 message_loop_.reset(); |
259 TraceLog::DeleteForTesting(); | 258 TraceLog::DeleteForTesting(); |
260 } | 259 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 302 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
304 | 303 |
305 bool IsPeriodicDumpingEnabled() const { | 304 bool IsPeriodicDumpingEnabled() const { |
306 return MemoryDumpScheduler::GetInstance()->is_enabled_for_testing(); | 305 return MemoryDumpScheduler::GetInstance()->is_enabled_for_testing(); |
307 } | 306 } |
308 | 307 |
309 int GetMaxConsecutiveFailuresCount() const { | 308 int GetMaxConsecutiveFailuresCount() const { |
310 return MemoryDumpManager::kMaxConsecutiveFailuresCount; | 309 return MemoryDumpManager::kMaxConsecutiveFailuresCount; |
311 } | 310 } |
312 | 311 |
| 312 const std::vector<MemoryDumpCallbackResult>* GetResults() const { |
| 313 return &results_; |
| 314 } |
| 315 |
313 const MemoryDumpProvider::Options kDefaultOptions; | 316 const MemoryDumpProvider::Options kDefaultOptions; |
314 std::unique_ptr<MemoryDumpManager> mdm_; | 317 std::unique_ptr<MemoryDumpManager> mdm_; |
315 GlobalMemoryDumpHandler global_dump_handler_; | 318 GlobalMemoryDumpHandler global_dump_handler_; |
316 bool last_callback_success_; | 319 bool last_callback_success_; |
317 | 320 |
| 321 // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback by |
| 322 // trimming off the result argument and calling the global callback. |
| 323 void ProcessDumpRecordingCallbackAdapter( |
| 324 GlobalMemoryDumpCallback callback, |
| 325 uint64_t dump_guid, |
| 326 bool success, |
| 327 const base::Optional<MemoryDumpCallbackResult>& result) { |
| 328 if (result.has_value()) { |
| 329 results_.push_back(result.value()); |
| 330 } |
| 331 callback.Run(dump_guid, success); |
| 332 } |
| 333 |
318 private: | 334 private: |
319 std::unique_ptr<MessageLoop> message_loop_; | 335 std::unique_ptr<MessageLoop> message_loop_; |
| 336 std::vector<MemoryDumpCallbackResult> results_; |
320 | 337 |
321 // We want our singleton torn down after each test. | 338 // We want our singleton torn down after each test. |
322 ShadowingAtExitManager at_exit_manager_; | 339 ShadowingAtExitManager at_exit_manager_; |
323 }; | 340 }; |
324 | 341 |
325 // Basic sanity checks. Registers a memory dump provider and checks that it is | 342 // Basic sanity checks. Registers a memory dump provider and checks that it is |
326 // called, but only when memory-infra is enabled. | 343 // called, but only when memory-infra is enabled. |
327 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 344 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
328 InitializeMemoryDumpManager(false /* is_coordinator */); | 345 InitializeMemoryDumpManager(false /* is_coordinator */); |
329 MockMemoryDumpProvider mdp; | 346 MockMemoryDumpProvider mdp; |
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 // The callback result should actually be false since (for the moment at | 1328 // The callback result should actually be false since (for the moment at |
1312 // least) a true result means that as well as the dump generally being | 1329 // least) a true result means that as well as the dump generally being |
1313 // successful we also managed to add the dump to the trace. | 1330 // successful we also managed to add the dump to the trace. |
1314 EXPECT_FALSE(last_callback_success_); | 1331 EXPECT_FALSE(last_callback_success_); |
1315 | 1332 |
1316 mdm_->Disable(); | 1333 mdm_->Disable(); |
1317 | 1334 |
1318 mdm_->UnregisterDumpProvider(&mdp); | 1335 mdm_->UnregisterDumpProvider(&mdp); |
1319 } | 1336 } |
1320 | 1337 |
| 1338 TEST_F(MemoryDumpManagerTest, TestSummaryComputation) { |
| 1339 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 1340 MockMemoryDumpProvider mdp; |
| 1341 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 1342 |
| 1343 const MemoryDumpSessionState* session_state = |
| 1344 mdm_->session_state_for_testing().get(); |
| 1345 |
| 1346 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) |
| 1347 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, |
| 1348 const GlobalMemoryDumpCallback& callback) { |
| 1349 ProcessMemoryDumpCallback process_callback = |
| 1350 Bind(&MemoryDumpManagerTest_TestSummaryComputation_Test:: |
| 1351 ProcessDumpRecordingCallbackAdapter, |
| 1352 Unretained(this), callback); |
| 1353 mdm_->CreateProcessDump(args, process_callback); |
| 1354 })); |
| 1355 |
| 1356 EXPECT_CALL(mdp, OnMemoryDump(_, _)) |
| 1357 .Times(1) |
| 1358 .WillRepeatedly(Invoke([session_state](const MemoryDumpArgs&, |
| 1359 ProcessMemoryDump* pmd) -> bool { |
| 1360 auto* size = MemoryAllocatorDump::kNameSize; |
| 1361 auto* bytes = MemoryAllocatorDump::kUnitsBytes; |
| 1362 const uint32_t kB = 1024; |
| 1363 |
| 1364 pmd->CreateAllocatorDump("malloc")->AddScalar(size, bytes, 1 * kB); |
| 1365 pmd->CreateAllocatorDump("malloc/ignored") |
| 1366 ->AddScalar(size, bytes, 99 * kB); |
| 1367 |
| 1368 pmd->CreateAllocatorDump("blink_gc")->AddScalar(size, bytes, 2 * kB); |
| 1369 pmd->CreateAllocatorDump("blink_gc/ignored") |
| 1370 ->AddScalar(size, bytes, 99 * kB); |
| 1371 |
| 1372 pmd->CreateAllocatorDump("v8/foo")->AddScalar(size, bytes, 1 * kB); |
| 1373 pmd->CreateAllocatorDump("v8/bar")->AddScalar(size, bytes, 2 * kB); |
| 1374 pmd->CreateAllocatorDump("v8")->AddScalar(size, bytes, 99 * kB); |
| 1375 |
| 1376 pmd->CreateAllocatorDump("partition_alloc") |
| 1377 ->AddScalar(size, bytes, 99 * kB); |
| 1378 pmd->CreateAllocatorDump("partition_alloc/allocated_objects") |
| 1379 ->AddScalar(size, bytes, 99 * kB); |
| 1380 pmd->CreateAllocatorDump("partition_alloc/allocated_objects/ignored") |
| 1381 ->AddScalar(size, bytes, 99 * kB); |
| 1382 pmd->CreateAllocatorDump("partition_alloc/partitions") |
| 1383 ->AddScalar(size, bytes, 99 * kB); |
| 1384 pmd->CreateAllocatorDump("partition_alloc/partitions/foo") |
| 1385 ->AddScalar(size, bytes, 2 * kB); |
| 1386 pmd->CreateAllocatorDump("partition_alloc/partitions/bar") |
| 1387 ->AddScalar(size, bytes, 2 * kB); |
| 1388 pmd->process_totals()->set_resident_set_bytes(5 * kB); |
| 1389 pmd->set_has_process_totals(); |
| 1390 return true; |
| 1391 })); |
| 1392 |
| 1393 last_callback_success_ = false; |
| 1394 |
| 1395 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1396 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1397 MemoryDumpLevelOfDetail::LIGHT); |
| 1398 DisableTracing(); |
| 1399 |
| 1400 // We shouldn't see any of the 99 values from above. |
| 1401 EXPECT_TRUE(last_callback_success_); |
| 1402 ASSERT_EQ(1u, GetResults()->size()); |
| 1403 MemoryDumpCallbackResult result = GetResults()->front(); |
| 1404 // For malloc we only count the root "malloc" not children "malloc/*". |
| 1405 EXPECT_EQ(1u, result.chrome_dump.malloc_total_kb); |
| 1406 // For blink_gc we only count the root "blink_gc" not children "blink_gc/*". |
| 1407 EXPECT_EQ(2u, result.chrome_dump.blink_gc_total_kb); |
| 1408 // For v8 we count the children ("v8/*") as the root total is not given. |
| 1409 EXPECT_EQ(3u, result.chrome_dump.v8_total_kb); |
| 1410 // partition_alloc has partition_alloc/allocated_objects/* which is a subset |
| 1411 // of partition_alloc/partitions/* so we only count the latter. |
| 1412 EXPECT_EQ(4u, result.chrome_dump.partition_alloc_total_kb); |
| 1413 // resident_set_kb should read from process_totals. |
| 1414 EXPECT_EQ(5u, result.os_dump.resident_set_kb); |
| 1415 }; |
| 1416 |
1321 } // namespace trace_event | 1417 } // namespace trace_event |
1322 } // namespace base | 1418 } // namespace base |
OLD | NEW |