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 |