| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 MOCK_METHOD0(Destructor, void()); | 152 MOCK_METHOD0(Destructor, void()); |
| 153 MOCK_METHOD2(OnMemoryDump, | 153 MOCK_METHOD2(OnMemoryDump, |
| 154 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); | 154 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); |
| 155 MOCK_METHOD1(PollFastMemoryTotal, void(uint64_t* memory_total)); | 155 MOCK_METHOD1(PollFastMemoryTotal, void(uint64_t* memory_total)); |
| 156 MOCK_METHOD0(SuspendFastMemoryPolling, void()); | 156 MOCK_METHOD0(SuspendFastMemoryPolling, void()); |
| 157 | 157 |
| 158 MockMemoryDumpProvider() : enable_mock_destructor(false) { | 158 MockMemoryDumpProvider() : enable_mock_destructor(false) { |
| 159 ON_CALL(*this, OnMemoryDump(_, _)) | 159 ON_CALL(*this, OnMemoryDump(_, _)) |
| 160 .WillByDefault( | 160 .WillByDefault( |
| 161 Invoke([](const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool { | 161 Invoke([](const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool { |
| 162 // |heap_profiler_serialization_state| should not be null under | |
| 163 // any circumstances when invoking a memory dump. The problem | |
| 164 // might arise in race conditions like crbug.com/600570 . | |
| 165 EXPECT_TRUE(pmd->heap_profiler_serialization_state().get() != | |
| 166 nullptr); | |
| 167 return true; | 162 return true; |
| 168 })); | 163 })); |
| 169 | 164 |
| 170 ON_CALL(*this, PollFastMemoryTotal(_)) | 165 ON_CALL(*this, PollFastMemoryTotal(_)) |
| 171 .WillByDefault( | 166 .WillByDefault( |
| 172 Invoke([](uint64_t* memory_total) -> void { NOTREACHED(); })); | 167 Invoke([](uint64_t* memory_total) -> void { NOTREACHED(); })); |
| 173 } | 168 } |
| 174 ~MockMemoryDumpProvider() override { | 169 ~MockMemoryDumpProvider() override { |
| 175 if (enable_mock_destructor) | 170 if (enable_mock_destructor) |
| 176 Destructor(); | 171 Destructor(); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 329 |
| 335 private: | 330 private: |
| 336 std::unique_ptr<MessageLoop> message_loop_; | 331 std::unique_ptr<MessageLoop> message_loop_; |
| 337 std::vector<MemoryDumpCallbackResult> results_; | 332 std::vector<MemoryDumpCallbackResult> results_; |
| 338 | 333 |
| 339 // We want our singleton torn down after each test. | 334 // We want our singleton torn down after each test. |
| 340 ShadowingAtExitManager at_exit_manager_; | 335 ShadowingAtExitManager at_exit_manager_; |
| 341 }; | 336 }; |
| 342 | 337 |
| 343 // Basic sanity checks. Registers a memory dump provider and checks that it is | 338 // Basic sanity checks. Registers a memory dump provider and checks that it is |
| 344 // called, but only when memory-infra is enabled. | 339 // called. |
| 345 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 340 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
| 346 InitializeMemoryDumpManager(false /* is_coordinator */); | 341 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 347 MockMemoryDumpProvider mdp; | 342 MockMemoryDumpProvider mdp; |
| 348 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 343 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 349 | 344 |
| 350 // Check that the dumper is not called if the memory category is not enabled. | |
| 351 EnableTracingWithLegacyCategories("foobar-but-not-memory"); | |
| 352 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(0); | |
| 353 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | |
| 354 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 355 MemoryDumpLevelOfDetail::DETAILED); | |
| 356 DisableTracing(); | |
| 357 | |
| 358 // Now repeat enabling the memory category and check that the dumper is | 345 // Now repeat enabling the memory category and check that the dumper is |
| 359 // invoked this time. | 346 // invoked this time. |
| 360 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 347 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 361 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); | 348 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); |
| 362 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | 349 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
| 363 for (int i = 0; i < 3; ++i) { | 350 for (int i = 0; i < 3; ++i) { |
| 364 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 351 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 365 MemoryDumpLevelOfDetail::DETAILED); | 352 MemoryDumpLevelOfDetail::DETAILED); |
| 366 } | 353 } |
| 367 DisableTracing(); | 354 DisableTracing(); |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 DisableTracing(); | 898 DisableTracing(); |
| 912 } | 899 } |
| 913 | 900 |
| 914 // Checks that a NACK callback is invoked if RequestGlobalDump() is called when | 901 // Checks that a NACK callback is invoked if RequestGlobalDump() is called when |
| 915 // tracing is not enabled. | 902 // tracing is not enabled. |
| 916 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { | 903 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { |
| 917 InitializeMemoryDumpManager(false /* is_coordinator */); | 904 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 918 MockMemoryDumpProvider mdp1; | 905 MockMemoryDumpProvider mdp1; |
| 919 RegisterDumpProvider(&mdp1, nullptr); | 906 RegisterDumpProvider(&mdp1, nullptr); |
| 920 | 907 |
| 921 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(0); | |
| 922 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | |
| 923 | |
| 924 last_callback_success_ = true; | 908 last_callback_success_ = true; |
| 925 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 909 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 926 MemoryDumpLevelOfDetail::DETAILED); | 910 MemoryDumpLevelOfDetail::DETAILED); |
| 927 EXPECT_FALSE(last_callback_success_); | 911 EXPECT_FALSE(last_callback_success_); |
| 928 } | 912 } |
| 929 | 913 |
| 930 // Checks that is the MemoryDumpManager is initialized after tracing already | 914 // Checks that is the MemoryDumpManager is initialized after tracing already |
| 931 // began, it will still late-join the party (real use case: startup tracing). | 915 // began, it will still late-join the party (real use case: startup tracing). |
| 932 TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { | 916 TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { |
| 933 MockMemoryDumpProvider mdp; | 917 MockMemoryDumpProvider mdp; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | 1030 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) |
| 1047 .Times(AnyNumber()); | 1031 .Times(AnyNumber()); |
| 1048 | 1032 |
| 1049 EnableTracingWithTraceConfig( | 1033 EnableTracingWithTraceConfig( |
| 1050 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( | 1034 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( |
| 1051 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); | 1035 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); |
| 1052 run_loop.Run(); | 1036 run_loop.Run(); |
| 1053 DisableTracing(); | 1037 DisableTracing(); |
| 1054 } | 1038 } |
| 1055 | 1039 |
| 1056 // Tests against race conditions that can happen if tracing is disabled before | |
| 1057 // the CreateProcessDump() call. Real-world regression: crbug.com/580295 . | |
| 1058 TEST_F(MemoryDumpManagerTest, DisableTracingRightBeforeStartOfDump) { | |
| 1059 base::WaitableEvent tracing_disabled_event( | |
| 1060 WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 1061 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 1062 InitializeMemoryDumpManager(false /* is_coordinator */); | |
| 1063 | |
| 1064 std::unique_ptr<Thread> mdp_thread(new Thread("test thread")); | |
| 1065 mdp_thread->Start(); | |
| 1066 | |
| 1067 // Create both same-thread MDP and another MDP with dedicated thread | |
| 1068 MockMemoryDumpProvider mdp1; | |
| 1069 RegisterDumpProvider(&mdp1, nullptr); | |
| 1070 MockMemoryDumpProvider mdp2; | |
| 1071 RegisterDumpProvider(&mdp2, mdp_thread->task_runner(), kDefaultOptions); | |
| 1072 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | |
| 1073 | |
| 1074 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | |
| 1075 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, | |
| 1076 const GlobalMemoryDumpCallback& callback) { | |
| 1077 DisableTracing(); | |
| 1078 ProcessMemoryDumpCallback process_callback = | |
| 1079 Bind(&ProcessDumpCallbackAdapter, callback); | |
| 1080 mdm_->CreateProcessDump(args, process_callback); | |
| 1081 })); | |
| 1082 | |
| 1083 // If tracing is disabled for current session CreateProcessDump() should NOT | |
| 1084 // request dumps from providers. Real-world regression: crbug.com/600570 . | |
| 1085 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | |
| 1086 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); | |
| 1087 | |
| 1088 last_callback_success_ = true; | |
| 1089 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 1090 MemoryDumpLevelOfDetail::DETAILED); | |
| 1091 EXPECT_FALSE(last_callback_success_); | |
| 1092 } | |
| 1093 | |
| 1094 TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) { | 1040 TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) { |
| 1095 using trace_analyzer::Query; | 1041 using trace_analyzer::Query; |
| 1096 | 1042 |
| 1097 InitializeMemoryDumpManager(false /* is_coordinator */); | 1043 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 1098 | 1044 |
| 1099 // Standard provider with default options (create dump for current process). | 1045 // Standard provider with default options (create dump for current process). |
| 1100 MemoryDumpProvider::Options options; | 1046 MemoryDumpProvider::Options options; |
| 1101 MockMemoryDumpProvider mdp1; | 1047 MockMemoryDumpProvider mdp1; |
| 1102 RegisterDumpProvider(&mdp1, nullptr, options); | 1048 RegisterDumpProvider(&mdp1, nullptr, options); |
| 1103 | 1049 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 // The callback result should actually be false since (for the moment at | 1269 // The callback result should actually be false since (for the moment at |
| 1324 // least) a true result means that as well as the dump generally being | 1270 // least) a true result means that as well as the dump generally being |
| 1325 // successful we also managed to add the dump to the trace. | 1271 // successful we also managed to add the dump to the trace. |
| 1326 EXPECT_FALSE(last_callback_success_); | 1272 EXPECT_FALSE(last_callback_success_); |
| 1327 | 1273 |
| 1328 mdm_->Disable(); | 1274 mdm_->Disable(); |
| 1329 | 1275 |
| 1330 mdm_->UnregisterDumpProvider(&mdp); | 1276 mdm_->UnregisterDumpProvider(&mdp); |
| 1331 } | 1277 } |
| 1332 | 1278 |
| 1279 // Tests that we can do a dump without enabling/disabling. |
| 1280 TEST_F(MemoryDumpManagerTest, DumpWithoutTracing) { |
| 1281 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 1282 MockMemoryDumpProvider mdp; |
| 1283 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 1284 |
| 1285 DisableTracing(); |
| 1286 |
| 1287 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); |
| 1288 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
| 1289 last_callback_success_ = true; |
| 1290 for (int i = 0; i < 3; ++i) |
| 1291 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1292 MemoryDumpLevelOfDetail::DETAILED); |
| 1293 // The callback result should be false since (for the moment at |
| 1294 // least) a true result means that as well as the dump being |
| 1295 // successful we also managed to add the dump to the trace which shouldn't |
| 1296 // happen when tracing is not enabled. |
| 1297 EXPECT_FALSE(last_callback_success_); |
| 1298 |
| 1299 mdm_->UnregisterDumpProvider(&mdp); |
| 1300 } |
| 1301 |
| 1333 TEST_F(MemoryDumpManagerTest, TestSummaryComputation) { | 1302 TEST_F(MemoryDumpManagerTest, TestSummaryComputation) { |
| 1334 InitializeMemoryDumpManager(false /* is_coordinator */); | 1303 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 1335 MockMemoryDumpProvider mdp; | 1304 MockMemoryDumpProvider mdp; |
| 1336 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 1305 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 1337 | 1306 |
| 1338 const HeapProfilerSerializationState* heap_profiler_serialization_state = | 1307 const HeapProfilerSerializationState* heap_profiler_serialization_state = |
| 1339 mdm_->heap_profiler_serialization_state_for_testing().get(); | 1308 mdm_->heap_profiler_serialization_state_for_testing().get(); |
| 1340 | 1309 |
| 1341 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | 1310 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) |
| 1342 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, | 1311 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 EXPECT_EQ(3u, result.chrome_dump.v8_total_kb); | 1374 EXPECT_EQ(3u, result.chrome_dump.v8_total_kb); |
| 1406 // partition_alloc has partition_alloc/allocated_objects/* which is a subset | 1375 // partition_alloc has partition_alloc/allocated_objects/* which is a subset |
| 1407 // of partition_alloc/partitions/* so we only count the latter. | 1376 // of partition_alloc/partitions/* so we only count the latter. |
| 1408 EXPECT_EQ(4u, result.chrome_dump.partition_alloc_total_kb); | 1377 EXPECT_EQ(4u, result.chrome_dump.partition_alloc_total_kb); |
| 1409 // resident_set_kb should read from process_totals. | 1378 // resident_set_kb should read from process_totals. |
| 1410 EXPECT_EQ(5u, result.os_dump.resident_set_kb); | 1379 EXPECT_EQ(5u, result.os_dump.resident_set_kb); |
| 1411 }; | 1380 }; |
| 1412 | 1381 |
| 1413 } // namespace trace_event | 1382 } // namespace trace_event |
| 1414 } // namespace base | 1383 } // namespace base |
| OLD | NEW |