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 <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/memory/ref_counted_memory.h" | 14 #include "base/memory/ref_counted_memory.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
17 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
18 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
19 #include "base/test/sequenced_worker_pool_owner.h" | 19 #include "base/test/sequenced_worker_pool_owner.h" |
20 #include "base/test/test_io_thread.h" | 20 #include "base/test/test_io_thread.h" |
21 #include "base/test/trace_event_analyzer.h" | 21 #include "base/test/trace_event_analyzer.h" |
22 #include "base/threading/platform_thread.h" | 22 #include "base/threading/platform_thread.h" |
23 #include "base/threading/sequenced_task_runner_handle.h" | 23 #include "base/threading/sequenced_task_runner_handle.h" |
24 #include "base/threading/sequenced_worker_pool.h" | 24 #include "base/threading/sequenced_worker_pool.h" |
25 #include "base/threading/thread.h" | 25 #include "base/threading/thread.h" |
26 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
27 #include "base/trace_event/memory_dump_provider.h" | 27 #include "base/trace_event/memory_dump_provider.h" |
| 28 #include "base/trace_event/memory_dump_trigger.h" |
28 #include "base/trace_event/memory_infra_background_whitelist.h" | 29 #include "base/trace_event/memory_infra_background_whitelist.h" |
29 #include "base/trace_event/process_memory_dump.h" | 30 #include "base/trace_event/process_memory_dump.h" |
30 #include "base/trace_event/trace_buffer.h" | 31 #include "base/trace_event/trace_buffer.h" |
31 #include "base/trace_event/trace_config_memory_test_util.h" | 32 #include "base/trace_event/trace_config_memory_test_util.h" |
32 #include "testing/gmock/include/gmock/gmock.h" | 33 #include "testing/gmock/include/gmock/gmock.h" |
33 #include "testing/gtest/include/gtest/gtest.h" | 34 #include "testing/gtest/include/gtest/gtest.h" |
34 | 35 |
35 using testing::_; | 36 using testing::_; |
36 using testing::AnyNumber; | 37 using testing::AnyNumber; |
37 using testing::AtMost; | 38 using testing::AtMost; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 TraceLog::RECORDING_MODE); | 264 TraceLog::RECORDING_MODE); |
264 } | 265 } |
265 | 266 |
266 void EnableTracingWithTraceConfig(const std::string& trace_config) { | 267 void EnableTracingWithTraceConfig(const std::string& trace_config) { |
267 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), | 268 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), |
268 TraceLog::RECORDING_MODE); | 269 TraceLog::RECORDING_MODE); |
269 } | 270 } |
270 | 271 |
271 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 272 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
272 | 273 |
273 bool IsPeriodicDumpingEnabled() const { | |
274 return mdm_->periodic_dump_timer_.IsRunning(); | |
275 } | |
276 | |
277 int GetMaxConsecutiveFailuresCount() const { | 274 int GetMaxConsecutiveFailuresCount() const { |
278 return MemoryDumpManager::kMaxConsecutiveFailuresCount; | 275 return MemoryDumpManager::kMaxConsecutiveFailuresCount; |
279 } | 276 } |
280 | 277 |
281 scoped_refptr<SequencedTaskRunner> GetPollingTaskRunnerUnsafe() { | 278 MemoryDumpTrigger* GetDumpTrigger() { return mdm_->dump_trigger_.get(); } |
282 return mdm_->dump_thread_->task_runner(); | |
283 } | |
284 | 279 |
285 const MemoryDumpProvider::Options kDefaultOptions; | 280 const MemoryDumpProvider::Options kDefaultOptions; |
286 std::unique_ptr<MemoryDumpManager> mdm_; | 281 std::unique_ptr<MemoryDumpManager> mdm_; |
287 std::unique_ptr<MemoryDumpManagerDelegateForTesting> delegate_; | 282 std::unique_ptr<MemoryDumpManagerDelegateForTesting> delegate_; |
288 bool last_callback_success_; | 283 bool last_callback_success_; |
289 | 284 |
290 private: | 285 private: |
291 std::unique_ptr<MessageLoop> message_loop_; | 286 std::unique_ptr<MessageLoop> message_loop_; |
292 | 287 |
293 // We want our singleton torn down after each test. | 288 // We want our singleton torn down after each test. |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); | 750 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); |
756 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); | 751 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); |
757 mdp1->enable_mock_destructor = true; | 752 mdp1->enable_mock_destructor = true; |
758 mdp2->enable_mock_destructor = true; | 753 mdp2->enable_mock_destructor = true; |
759 | 754 |
760 EXPECT_CALL(*mdp1, SuspendFastMemoryPolling()).Times(1); | 755 EXPECT_CALL(*mdp1, SuspendFastMemoryPolling()).Times(1); |
761 EXPECT_CALL(*mdp2, SuspendFastMemoryPolling()).Times(1); | 756 EXPECT_CALL(*mdp2, SuspendFastMemoryPolling()).Times(1); |
762 EXPECT_CALL(*mdp1, Destructor()); | 757 EXPECT_CALL(*mdp1, Destructor()); |
763 EXPECT_CALL(*mdp2, Destructor()); | 758 EXPECT_CALL(*mdp2, Destructor()); |
764 | 759 |
| 760 MemoryDumpProvider::Options options; |
| 761 options.is_fast_polling_supported = true; |
| 762 RegisterDumpProvider(mdp1.get(), nullptr, options); |
| 763 |
765 RunLoop run_loop; | 764 RunLoop run_loop; |
766 scoped_refptr<SingleThreadTaskRunner> test_task_runner = | 765 scoped_refptr<SingleThreadTaskRunner> test_task_runner = |
767 ThreadTaskRunnerHandle::Get(); | 766 ThreadTaskRunnerHandle::Get(); |
768 auto quit_closure = run_loop.QuitClosure(); | 767 auto quit_closure = run_loop.QuitClosure(); |
769 | 768 |
| 769 const int kPollsToQuit = 10; |
770 int call_count = 0; | 770 int call_count = 0; |
| 771 MemoryDumpManager* mdm = mdm_.get(); |
| 772 const auto poll_function1 = [&call_count, &test_task_runner, quit_closure, |
| 773 &mdp2, mdm, &options, |
| 774 this](uint64_t* total) -> void { |
| 775 ++call_count; |
| 776 if (call_count == 1) |
| 777 RegisterDumpProvider(mdp2.get(), nullptr, options, kMDPName); |
| 778 else if (call_count == 4) |
| 779 mdm->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2)); |
| 780 else if (call_count == kPollsToQuit) |
| 781 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 782 |
| 783 // Record increase of 10s of GiB of memory. |
| 784 *total = call_count * 10lu * 1024 * 1024 * 1024; |
| 785 }; |
771 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_)) | 786 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_)) |
772 .Times(4) | 787 .Times(testing::AtLeast(kPollsToQuit)) |
773 .WillRepeatedly(Invoke([&call_count, &test_task_runner, | 788 .WillRepeatedly(Invoke(poll_function1)); |
774 quit_closure](uint64_t* total) -> void { | |
775 ++call_count; | |
776 if (call_count == 4) | |
777 test_task_runner->PostTask(FROM_HERE, quit_closure); | |
778 })); | |
779 | 789 |
780 // Depending on the order of PostTask calls the mdp2 might be registered after | 790 // Depending on the order of PostTask calls the mdp2 might be registered after |
781 // all polls or in between polls. | 791 // all polls or in between polls. |
782 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_)) | 792 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_)) |
783 .Times(Between(0, 4)) | 793 .Times(Between(0, kPollsToQuit - 1)) |
784 .WillRepeatedly(Return()); | 794 .WillRepeatedly(Return()); |
785 | 795 |
786 MemoryDumpProvider::Options options; | 796 MemoryDumpTrigger::SetPollingIntervalForTesting(1); |
787 options.is_fast_polling_supported = true; | |
788 RegisterDumpProvider(mdp1.get(), nullptr, options); | |
789 EnableTracingWithTraceConfig( | 797 EnableTracingWithTraceConfig( |
790 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(1)); | 798 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(3)); |
791 scoped_refptr<SequencedTaskRunner> polling_task_runner = | |
792 GetPollingTaskRunnerUnsafe().get(); | |
793 ASSERT_TRUE(polling_task_runner); | |
794 | 799 |
795 uint64_t value = 0; | 800 int last_poll_to_request_dump = -2; |
796 for (int i = 0; i < 4; i++) { | 801 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)) |
797 if (i == 0) | 802 .Times(testing::AtLeast(2)) |
798 RegisterDumpProvider(mdp2.get(), nullptr, options); | 803 .WillRepeatedly(Invoke([&last_poll_to_request_dump, &call_count]( |
799 if (i == 2) | 804 const MemoryDumpRequestArgs& args, |
800 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2)); | 805 const MemoryDumpCallback& callback) -> void { |
801 polling_task_runner->PostTask( | 806 // Minimum number of polls between dumps must be 3 (polling interval is |
802 FROM_HERE, Bind(&MemoryDumpManagerTest::PollFastMemoryTotal, | 807 // 1ms). |
803 Unretained(this), &value)); | 808 EXPECT_GE(call_count - last_poll_to_request_dump, 3); |
804 } | 809 last_poll_to_request_dump = call_count; |
| 810 })); |
805 | 811 |
806 run_loop.Run(); | 812 run_loop.Run(); |
807 DisableTracing(); | 813 DisableTracing(); |
808 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); | 814 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); |
809 } | 815 } |
810 | 816 |
811 // If a thread (with a dump provider living on it) is torn down during a dump | 817 // If a thread (with a dump provider living on it) is torn down during a dump |
812 // its dump provider should be skipped but the dump itself should succeed. | 818 // its dump provider should be skipped but the dump itself should succeed. |
813 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { | 819 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { |
814 InitializeMemoryDumpManager(false /* is_coordinator */); | 820 InitializeMemoryDumpManager(false /* is_coordinator */); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 // Don't trigger the default behavior of the mock delegate in this test, | 923 // Don't trigger the default behavior of the mock delegate in this test, |
918 // which would short-circuit the dump request to the actual | 924 // which would short-circuit the dump request to the actual |
919 // CreateProcessDump(). | 925 // CreateProcessDump(). |
920 // We don't want to create any dump in this test, only check whether the dumps | 926 // We don't want to create any dump in this test, only check whether the dumps |
921 // are requested or not. | 927 // are requested or not. |
922 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); | 928 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); |
923 | 929 |
924 // Enabling memory-infra in a non-coordinator process should not trigger any | 930 // Enabling memory-infra in a non-coordinator process should not trigger any |
925 // periodic dumps. | 931 // periodic dumps. |
926 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 932 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
927 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 933 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
928 DisableTracing(); | 934 DisableTracing(); |
929 | 935 |
930 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator | 936 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator |
931 // process with a fully defined trigger config should NOT enable any periodic | 937 // process with a fully defined trigger config should NOT enable any periodic |
932 // dumps. | 938 // dumps. |
933 EnableTracingWithTraceConfig( | 939 EnableTracingWithTraceConfig( |
934 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5)); | 940 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5)); |
935 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 941 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
936 DisableTracing(); | 942 DisableTracing(); |
937 } | 943 } |
938 | 944 |
939 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { | 945 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { |
940 InitializeMemoryDumpManager(true /* is_coordinator */); | 946 InitializeMemoryDumpManager(true /* is_coordinator */); |
941 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; | 947 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; |
942 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); | 948 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); |
943 | 949 |
944 // Enabling memory-infra with the legacy TraceConfig (category filter) in | 950 // Enabling memory-infra with the legacy TraceConfig (category filter) in |
945 // a coordinator process should enable periodic dumps. | 951 // a coordinator process should enable periodic dumps. |
946 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 952 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
947 EXPECT_TRUE(IsPeriodicDumpingEnabled()); | 953 EXPECT_TRUE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
948 DisableTracing(); | 954 DisableTracing(); |
949 | 955 |
950 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 956 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
951 // process without specifying any "memory_dump_config" section should enable | 957 // process without specifying any "memory_dump_config" section should enable |
952 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that | 958 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that |
953 // is: ticking memory-infra should dump periodically with the default config. | 959 // is: ticking memory-infra should dump periodically with the default config. |
954 EnableTracingWithTraceConfig( | 960 EnableTracingWithTraceConfig( |
955 TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers()); | 961 TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers()); |
956 EXPECT_TRUE(IsPeriodicDumpingEnabled()); | 962 EXPECT_TRUE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
957 DisableTracing(); | 963 DisableTracing(); |
958 | 964 |
959 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 965 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
960 // process with an empty "memory_dump_config" should NOT enable periodic | 966 // process with an empty "memory_dump_config" should NOT enable periodic |
961 // dumps. This is the way telemetry is supposed to use memory-infra with | 967 // dumps. This is the way telemetry is supposed to use memory-infra with |
962 // only explicitly triggered dumps. | 968 // only explicitly triggered dumps. |
963 EnableTracingWithTraceConfig( | 969 EnableTracingWithTraceConfig( |
964 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); | 970 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); |
965 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 971 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
966 DisableTracing(); | 972 DisableTracing(); |
967 | 973 |
968 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 974 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
969 // process with a fully defined trigger config should cause periodic dumps to | 975 // process with a fully defined trigger config should cause periodic dumps to |
970 // be performed in the correct order. | 976 // be performed in the correct order. |
971 RunLoop run_loop; | 977 RunLoop run_loop; |
972 auto quit_closure = run_loop.QuitClosure(); | 978 auto quit_closure = run_loop.QuitClosure(); |
973 | 979 |
974 const int kHeavyDumpRate = 5; | 980 const int kHeavyDumpRate = 5; |
975 const int kLightDumpPeriodMs = 1; | 981 const int kLightDumpPeriodMs = 1; |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 RegisterDumpProvider(mdp1.get()); | 1222 RegisterDumpProvider(mdp1.get()); |
1217 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider); | 1223 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider); |
1218 RegisterDumpProvider(mdp2.get(), nullptr, kDefaultOptions, | 1224 RegisterDumpProvider(mdp2.get(), nullptr, kDefaultOptions, |
1219 kWhitelistedMDPName); | 1225 kWhitelistedMDPName); |
1220 | 1226 |
1221 EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0); | 1227 EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0); |
1222 EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1).WillOnce(Return(true)); | 1228 EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1).WillOnce(Return(true)); |
1223 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); | 1229 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
1224 | 1230 |
1225 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1231 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
1226 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 1232 EXPECT_FALSE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
1227 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1233 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
1228 MemoryDumpLevelOfDetail::BACKGROUND); | 1234 MemoryDumpLevelOfDetail::BACKGROUND); |
1229 DisableTracing(); | 1235 DisableTracing(); |
1230 } | 1236 } |
1231 | 1237 |
1232 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { | 1238 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { |
1233 InitializeMemoryDumpManager(true /* is_coordinator */); | 1239 InitializeMemoryDumpManager(true /* is_coordinator */); |
1234 | 1240 |
1235 RunLoop run_loop; | 1241 RunLoop run_loop; |
1236 auto quit_closure = run_loop.QuitClosure(); | 1242 auto quit_closure = run_loop.QuitClosure(); |
(...skipping 15 matching lines...) Expand all Loading... |
1252 // Only background mode dumps should be allowed with the trace config. | 1258 // Only background mode dumps should be allowed with the trace config. |
1253 last_callback_success_ = false; | 1259 last_callback_success_ = false; |
1254 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1260 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
1255 MemoryDumpLevelOfDetail::LIGHT); | 1261 MemoryDumpLevelOfDetail::LIGHT); |
1256 EXPECT_FALSE(last_callback_success_); | 1262 EXPECT_FALSE(last_callback_success_); |
1257 last_callback_success_ = false; | 1263 last_callback_success_ = false; |
1258 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1264 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
1259 MemoryDumpLevelOfDetail::DETAILED); | 1265 MemoryDumpLevelOfDetail::DETAILED); |
1260 EXPECT_FALSE(last_callback_success_); | 1266 EXPECT_FALSE(last_callback_success_); |
1261 | 1267 |
1262 ASSERT_TRUE(IsPeriodicDumpingEnabled()); | 1268 ASSERT_TRUE(GetDumpTrigger()->IsPeriodicDumpTimerRunning()); |
1263 run_loop.Run(); | 1269 run_loop.Run(); |
1264 DisableTracing(); | 1270 DisableTracing(); |
1265 } | 1271 } |
1266 | 1272 |
1267 } // namespace trace_event | 1273 } // namespace trace_event |
1268 } // namespace base | 1274 } // namespace base |
OLD | NEW |