Chromium Code Reviews| 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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 // Turns a Closure into a MemoryDumpCallback, keeping track of the callback | 237 // Turns a Closure into a MemoryDumpCallback, keeping track of the callback |
| 238 // result and taking care of posting the closure on the correct task runner. | 238 // result and taking care of posting the closure on the correct task runner. |
| 239 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, | 239 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, |
| 240 Closure closure, | 240 Closure closure, |
| 241 uint64_t dump_guid, | 241 uint64_t dump_guid, |
| 242 bool success) { | 242 bool success) { |
| 243 last_callback_success_ = success; | 243 last_callback_success_ = success; |
| 244 task_runner->PostTask(FROM_HERE, closure); | 244 task_runner->PostTask(FROM_HERE, closure); |
| 245 } | 245 } |
| 246 | 246 |
| 247 void PollFastMemoryTotal(uint64_t* memory_total) { | |
| 248 mdm_->PollFastMemoryTotal(memory_total); | |
| 249 } | |
| 250 | |
| 251 protected: | 247 protected: |
| 252 void InitializeMemoryDumpManager(bool is_coordinator) { | 248 void InitializeMemoryDumpManager(bool is_coordinator) { |
| 253 mdm_->set_dumper_registrations_ignored_for_testing(true); | 249 mdm_->set_dumper_registrations_ignored_for_testing(true); |
| 254 delegate_ = new MemoryDumpManagerDelegateForTesting(is_coordinator); | 250 delegate_ = new MemoryDumpManagerDelegateForTesting(is_coordinator); |
| 255 mdm_->Initialize(base::WrapUnique(delegate_)); | 251 mdm_->Initialize(base::WrapUnique(delegate_)); |
| 256 } | 252 } |
| 257 | 253 |
| 258 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, | 254 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, |
| 259 MemoryDumpLevelOfDetail level_of_detail) { | 255 MemoryDumpLevelOfDetail level_of_detail) { |
| 260 RunLoop run_loop; | 256 RunLoop run_loop; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 271 } | 267 } |
| 272 | 268 |
| 273 void EnableTracingWithTraceConfig(const std::string& trace_config) { | 269 void EnableTracingWithTraceConfig(const std::string& trace_config) { |
| 274 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), | 270 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), |
| 275 TraceLog::RECORDING_MODE); | 271 TraceLog::RECORDING_MODE); |
| 276 } | 272 } |
| 277 | 273 |
| 278 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 274 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
| 279 | 275 |
| 280 bool IsPeriodicDumpingEnabled() const { | 276 bool IsPeriodicDumpingEnabled() const { |
| 281 return MemoryDumpScheduler::GetInstance() | 277 return MemoryDumpScheduler::GetInstance()->is_enabled_for_testing(); |
| 282 ->IsPeriodicTimerRunningForTesting(); | |
| 283 } | 278 } |
| 284 | 279 |
| 285 int GetMaxConsecutiveFailuresCount() const { | 280 int GetMaxConsecutiveFailuresCount() const { |
| 286 return MemoryDumpManager::kMaxConsecutiveFailuresCount; | 281 return MemoryDumpManager::kMaxConsecutiveFailuresCount; |
| 287 } | 282 } |
| 288 | 283 |
| 289 const MemoryDumpProvider::Options kDefaultOptions; | 284 const MemoryDumpProvider::Options kDefaultOptions; |
| 290 std::unique_ptr<MemoryDumpManager> mdm_; | 285 std::unique_ptr<MemoryDumpManager> mdm_; |
| 291 MemoryDumpManagerDelegateForTesting* delegate_; | 286 MemoryDumpManagerDelegateForTesting* delegate_; |
| 292 bool last_callback_success_; | 287 bool last_callback_success_; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 | 754 |
| 760 DisableTracing(); | 755 DisableTracing(); |
| 761 } | 756 } |
| 762 | 757 |
| 763 TEST_F(MemoryDumpManagerTest, TestPollingOnDumpThread) { | 758 TEST_F(MemoryDumpManagerTest, TestPollingOnDumpThread) { |
| 764 InitializeMemoryDumpManager(false /* is_coordinator */); | 759 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 765 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); | 760 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); |
| 766 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); | 761 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); |
| 767 mdp1->enable_mock_destructor = true; | 762 mdp1->enable_mock_destructor = true; |
| 768 mdp2->enable_mock_destructor = true; | 763 mdp2->enable_mock_destructor = true; |
| 769 | |
| 770 EXPECT_CALL(*mdp1, SuspendFastMemoryPolling()).Times(1); | |
| 771 EXPECT_CALL(*mdp2, SuspendFastMemoryPolling()).Times(1); | |
| 772 EXPECT_CALL(*mdp1, Destructor()); | 764 EXPECT_CALL(*mdp1, Destructor()); |
| 773 EXPECT_CALL(*mdp2, Destructor()); | 765 EXPECT_CALL(*mdp2, Destructor()); |
| 774 | 766 |
| 775 MemoryDumpProvider::Options options; | 767 MemoryDumpProvider::Options options; |
| 776 options.is_fast_polling_supported = true; | 768 options.is_fast_polling_supported = true; |
| 777 RegisterDumpProvider(mdp1.get(), nullptr, options); | 769 RegisterDumpProvider(mdp1.get(), nullptr, options); |
| 778 | 770 |
| 779 RunLoop run_loop; | 771 RunLoop run_loop; |
| 780 scoped_refptr<SingleThreadTaskRunner> test_task_runner = | 772 auto test_task_runner = ThreadTaskRunnerHandle::Get(); |
| 781 ThreadTaskRunnerHandle::Get(); | |
| 782 auto quit_closure = run_loop.QuitClosure(); | 773 auto quit_closure = run_loop.QuitClosure(); |
| 774 MemoryDumpManager* mdm = mdm_.get(); | |
| 783 | 775 |
| 784 const int kPollsToQuit = 10; | |
| 785 int call_count = 0; | |
| 786 MemoryDumpManager* mdm = mdm_.get(); | |
| 787 const auto poll_function1 = [&call_count, &test_task_runner, quit_closure, | |
| 788 &mdp2, mdm, &options, kPollsToQuit, | |
| 789 this](uint64_t* total) -> void { | |
| 790 ++call_count; | |
| 791 if (call_count == 1) | |
| 792 RegisterDumpProvider(mdp2.get(), nullptr, options, kMDPName); | |
| 793 else if (call_count == 4) | |
| 794 mdm->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2)); | |
| 795 else if (call_count == kPollsToQuit) | |
| 796 test_task_runner->PostTask(FROM_HERE, quit_closure); | |
| 797 | |
| 798 // Record increase of 1 GiB of memory at each call. | |
| 799 *total = static_cast<uint64_t>(call_count) * 1024 * 1024 * 1024; | |
| 800 }; | |
| 801 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_)) | 776 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_)) |
| 802 .Times(testing::AtLeast(kPollsToQuit)) | 777 .WillOnce(Invoke([&mdp2, options, this](uint64_t*) { |
| 803 .WillRepeatedly(Invoke(poll_function1)); | 778 RegisterDumpProvider(mdp2.get(), nullptr, options); |
| 804 | 779 })) |
| 805 // Depending on the order of PostTask calls the mdp2 might be registered after | 780 .WillOnce(Return()) |
| 806 // all polls or in between polls. | 781 .WillOnce(Invoke([mdm, &mdp2](uint64_t*) { |
| 807 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_)) | 782 mdm->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2)); |
| 808 .Times(Between(0, kPollsToQuit - 1)) | 783 })) |
| 784 .WillOnce(Invoke([test_task_runner, quit_closure](uint64_t*) { | |
| 785 test_task_runner->PostTask(FROM_HERE, quit_closure); | |
| 786 })) | |
| 809 .WillRepeatedly(Return()); | 787 .WillRepeatedly(Return()); |
| 810 | 788 |
| 811 MemoryDumpScheduler::SetPollingIntervalForTesting(1); | 789 EXPECT_CALL(*mdp1, SuspendFastMemoryPolling()).Times(1); |
|
ssid
2017/04/10 21:35:51
Why not
EXPECT_CALL(*mdp2, SuspendFastMemoryPoll
Primiano Tucci (use gerrit)
2017/04/11 11:43:08
Because I realized that there is no point calling
ssid
2017/04/11 17:47:30
Haha true!
| |
| 790 | |
| 791 // |mdp2| should invoke exactly twice: | |
| 792 // - once after the registrarion, when |mdp1| hits the first Return() | |
| 793 // - the 2nd time when |mdp1| unregisters |mdp1|. The unregistration is | |
| 794 // posted and will necessarily happen after the polling task. | |
| 795 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_)).Times(2).WillRepeatedly(Return()); | |
| 796 | |
| 812 EnableTracingWithTraceConfig( | 797 EnableTracingWithTraceConfig( |
| 813 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(3)); | 798 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(1)); |
| 814 | |
| 815 int last_poll_to_request_dump = -2; | |
| 816 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)) | |
| 817 .Times(testing::AtLeast(2)) | |
| 818 .WillRepeatedly(Invoke([&last_poll_to_request_dump, &call_count]( | |
| 819 const MemoryDumpRequestArgs& args, | |
| 820 const MemoryDumpCallback& callback) -> void { | |
| 821 // Minimum number of polls between dumps must be 3 (polling interval is | |
| 822 // 1ms). | |
| 823 EXPECT_GE(call_count - last_poll_to_request_dump, 3); | |
| 824 last_poll_to_request_dump = call_count; | |
| 825 })); | |
| 826 | |
| 827 run_loop.Run(); | 799 run_loop.Run(); |
| 828 DisableTracing(); | 800 DisableTracing(); |
| 829 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); | 801 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); |
| 830 } | 802 } |
| 831 | 803 |
| 832 // If a thread (with a dump provider living on it) is torn down during a dump | 804 // If a thread (with a dump provider living on it) is torn down during a dump |
| 833 // its dump provider should be skipped but the dump itself should succeed. | 805 // its dump provider should be skipped but the dump itself should succeed. |
| 834 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { | 806 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { |
| 835 InitializeMemoryDumpManager(false /* is_coordinator */); | 807 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 836 std::vector<std::unique_ptr<TestIOThread>> threads; | 808 std::vector<std::unique_ptr<TestIOThread>> threads; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 982 // only explicitly triggered dumps. | 954 // only explicitly triggered dumps. |
| 983 EnableTracingWithTraceConfig( | 955 EnableTracingWithTraceConfig( |
| 984 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); | 956 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); |
| 985 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 957 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 986 DisableTracing(); | 958 DisableTracing(); |
| 987 | 959 |
| 988 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 960 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
| 989 // process with a fully defined trigger config should cause periodic dumps to | 961 // process with a fully defined trigger config should cause periodic dumps to |
| 990 // be performed in the correct order. | 962 // be performed in the correct order. |
| 991 RunLoop run_loop; | 963 RunLoop run_loop; |
| 964 auto test_task_runner = ThreadTaskRunnerHandle::Get(); | |
| 992 auto quit_closure = run_loop.QuitClosure(); | 965 auto quit_closure = run_loop.QuitClosure(); |
| 993 | 966 |
| 994 const int kHeavyDumpRate = 5; | 967 const int kHeavyDumpRate = 5; |
| 995 const int kLightDumpPeriodMs = 1; | 968 const int kLightDumpPeriodMs = 1; |
| 996 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; | 969 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; |
| 997 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... | 970 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... |
| 998 testing::InSequence sequence; | 971 testing::InSequence sequence; |
| 999 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); | 972 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); |
| 1000 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) | 973 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) |
| 1001 .Times(kHeavyDumpRate - 1); | 974 .Times(kHeavyDumpRate - 1); |
| 1002 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); | 975 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsDetailedDump(), _)); |
| 1003 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) | 976 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) |
| 1004 .Times(kHeavyDumpRate - 2); | 977 .Times(kHeavyDumpRate - 2); |
| 1005 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) | 978 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLightDump(), _)) |
| 1006 .WillOnce(Invoke([quit_closure](const MemoryDumpRequestArgs& args, | 979 .WillOnce(Invoke( |
| 1007 const MemoryDumpCallback& callback) { | 980 [test_task_runner, quit_closure](const MemoryDumpRequestArgs& args, |
| 1008 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure); | 981 const MemoryDumpCallback& callback) { |
| 1009 })); | 982 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 983 })); | |
| 1010 | 984 |
| 1011 // Swallow all the final spurious calls until tracing gets disabled. | 985 // Swallow all the final spurious calls until tracing gets disabled. |
| 1012 EXPECT_CALL(delegate, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); | 986 EXPECT_CALL(delegate, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); |
| 1013 | 987 |
| 1014 EnableTracingWithTraceConfig( | 988 EnableTracingWithTraceConfig( |
| 1015 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( | 989 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( |
| 1016 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); | 990 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); |
| 1017 run_loop.Run(); | 991 run_loop.Run(); |
| 1018 DisableTracing(); | 992 DisableTracing(); |
| 1019 } | 993 } |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1252 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 1226 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 1253 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1227 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1254 MemoryDumpLevelOfDetail::BACKGROUND); | 1228 MemoryDumpLevelOfDetail::BACKGROUND); |
| 1255 DisableTracing(); | 1229 DisableTracing(); |
| 1256 } | 1230 } |
| 1257 | 1231 |
| 1258 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { | 1232 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { |
| 1259 InitializeMemoryDumpManager(true /* is_coordinator */); | 1233 InitializeMemoryDumpManager(true /* is_coordinator */); |
| 1260 | 1234 |
| 1261 RunLoop run_loop; | 1235 RunLoop run_loop; |
| 1236 auto test_task_runner = ThreadTaskRunnerHandle::Get(); | |
| 1262 auto quit_closure = run_loop.QuitClosure(); | 1237 auto quit_closure = run_loop.QuitClosure(); |
| 1263 | 1238 |
| 1264 testing::InSequence sequence; | 1239 testing::InSequence sequence; |
| 1265 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) | 1240 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) |
| 1266 .Times(5); | 1241 .Times(5); |
| 1267 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) | 1242 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(IsBackgroundDump(), _)) |
| 1268 .WillOnce(Invoke([quit_closure](const MemoryDumpRequestArgs& args, | 1243 .WillOnce(Invoke( |
| 1269 const MemoryDumpCallback& callback) { | 1244 [test_task_runner, quit_closure](const MemoryDumpRequestArgs& args, |
| 1270 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure); | 1245 const MemoryDumpCallback& callback) { |
| 1271 })); | 1246 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 1247 })); | |
| 1272 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); | 1248 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); |
| 1273 | 1249 |
| 1274 EnableTracingWithTraceConfig( | 1250 EnableTracingWithTraceConfig( |
| 1275 TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger( | 1251 TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger( |
| 1276 1 /* period_ms */)); | 1252 1 /* period_ms */)); |
| 1277 | 1253 |
| 1278 // Only background mode dumps should be allowed with the trace config. | 1254 // Only background mode dumps should be allowed with the trace config. |
| 1279 last_callback_success_ = false; | 1255 last_callback_success_ = false; |
| 1280 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1256 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1281 MemoryDumpLevelOfDetail::LIGHT); | 1257 MemoryDumpLevelOfDetail::LIGHT); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1302 thread.Start(); | 1278 thread.Start(); |
| 1303 RegisterDumpProvider(&mdp1, thread.task_runner(), kDefaultOptions, | 1279 RegisterDumpProvider(&mdp1, thread.task_runner(), kDefaultOptions, |
| 1304 "BlacklistTestDumpProvider"); | 1280 "BlacklistTestDumpProvider"); |
| 1305 // Unregistering on wrong thread should not crash. | 1281 // Unregistering on wrong thread should not crash. |
| 1306 mdm_->UnregisterDumpProvider(&mdp1); | 1282 mdm_->UnregisterDumpProvider(&mdp1); |
| 1307 thread.Stop(); | 1283 thread.Stop(); |
| 1308 } | 1284 } |
| 1309 | 1285 |
| 1310 } // namespace trace_event | 1286 } // namespace trace_event |
| 1311 } // namespace base | 1287 } // namespace base |
| OLD | NEW |