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 <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 | 143 |
144 // static | 144 // static |
145 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { | 145 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
146 g_instance_for_testing = instance; | 146 g_instance_for_testing = instance; |
147 } | 147 } |
148 | 148 |
149 MemoryDumpManager::MemoryDumpManager() | 149 MemoryDumpManager::MemoryDumpManager() |
150 : delegate_(nullptr), | 150 : delegate_(nullptr), |
151 is_coordinator_(false), | 151 is_coordinator_(false), |
152 memory_tracing_enabled_(0), | 152 memory_tracing_enabled_(0), |
| 153 periodic_dump_timer_(this), |
153 dump_provider_whitelist_(kDumpProviderWhitelist), | 154 dump_provider_whitelist_(kDumpProviderWhitelist), |
154 tracing_process_id_(kInvalidTracingProcessId), | 155 tracing_process_id_(kInvalidTracingProcessId), |
155 dumper_registrations_ignored_for_testing_(false), | 156 dumper_registrations_ignored_for_testing_(false), |
156 heap_profiling_enabled_(false) { | 157 heap_profiling_enabled_(false) { |
157 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 158 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
158 | 159 |
159 // At this point the command line may not be initialized but we try to | 160 // At this point the command line may not be initialized but we try to |
160 // enable the heap profiler to capture allocations as soon as possible. | 161 // enable the heap profiler to capture allocations as soon as possible. |
161 EnableHeapProfilingIfNeeded(); | 162 EnableHeapProfilingIfNeeded(); |
162 } | 163 } |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 // to just skip it, without actually invoking the |mdp|, which might be | 350 // to just skip it, without actually invoking the |mdp|, which might be |
350 // destroyed by the caller soon after this method returns. | 351 // destroyed by the caller soon after this method returns. |
351 (*mdp_iter)->disabled = true; | 352 (*mdp_iter)->disabled = true; |
352 dump_providers_.erase(mdp_iter); | 353 dump_providers_.erase(mdp_iter); |
353 } | 354 } |
354 | 355 |
355 void MemoryDumpManager::RequestGlobalDump( | 356 void MemoryDumpManager::RequestGlobalDump( |
356 MemoryDumpType dump_type, | 357 MemoryDumpType dump_type, |
357 MemoryDumpLevelOfDetail level_of_detail, | 358 MemoryDumpLevelOfDetail level_of_detail, |
358 const MemoryDumpCallback& callback) { | 359 const MemoryDumpCallback& callback) { |
359 // Bail out immediately if tracing is not enabled at all. | 360 // Bail out immediately if tracing is not enabled at all or if the dump mode |
360 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) { | 361 // is not allowed. |
| 362 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_)) || |
| 363 !IsDumpModeAllowed(level_of_detail)) { |
361 if (!callback.is_null()) | 364 if (!callback.is_null()) |
362 callback.Run(0u /* guid */, false /* success */); | 365 callback.Run(0u /* guid */, false /* success */); |
363 return; | 366 return; |
364 } | 367 } |
365 | 368 |
366 const uint64_t guid = | 369 const uint64_t guid = |
367 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); | 370 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); |
368 | 371 |
369 // Creates an async event to keep track of the global dump evolution. | 372 // Creates an async event to keep track of the global dump evolution. |
370 // The |wrapped_callback| will generate the ASYNC_END event and then invoke | 373 // The |wrapped_callback| will generate the ASYNC_END event and then invoke |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 | 644 |
642 // Spin-up the thread used to invoke unbound dump providers. | 645 // Spin-up the thread used to invoke unbound dump providers. |
643 std::unique_ptr<Thread> dump_thread(new Thread("MemoryInfra")); | 646 std::unique_ptr<Thread> dump_thread(new Thread("MemoryInfra")); |
644 if (!dump_thread->Start()) { | 647 if (!dump_thread->Start()) { |
645 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; | 648 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; |
646 return; | 649 return; |
647 } | 650 } |
648 | 651 |
649 const TraceConfig trace_config = | 652 const TraceConfig trace_config = |
650 TraceLog::GetInstance()->GetCurrentTraceConfig(); | 653 TraceLog::GetInstance()->GetCurrentTraceConfig(); |
| 654 allowed_dump_modes_ = trace_config.memory_dump_config().allowed_dump_modes; |
651 scoped_refptr<MemoryDumpSessionState> session_state = | 655 scoped_refptr<MemoryDumpSessionState> session_state = |
652 new MemoryDumpSessionState; | 656 new MemoryDumpSessionState; |
653 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config()); | 657 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config()); |
654 if (heap_profiling_enabled_) { | 658 if (heap_profiling_enabled_) { |
655 // If heap profiling is enabled, the stack frame deduplicator and type name | 659 // If heap profiling is enabled, the stack frame deduplicator and type name |
656 // deduplicator will be in use. Add a metadata events to write the frames | 660 // deduplicator will be in use. Add a metadata events to write the frames |
657 // and type IDs. | 661 // and type IDs. |
658 session_state->SetStackFrameDeduplicator( | 662 session_state->SetStackFrameDeduplicator( |
659 WrapUnique(new StackFrameDeduplicator)); | 663 WrapUnique(new StackFrameDeduplicator)); |
660 | 664 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid) { | 777 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid) { |
774 auto iter = process_dumps.find(pid); | 778 auto iter = process_dumps.find(pid); |
775 if (iter == process_dumps.end()) { | 779 if (iter == process_dumps.end()) { |
776 std::unique_ptr<ProcessMemoryDump> new_pmd( | 780 std::unique_ptr<ProcessMemoryDump> new_pmd( |
777 new ProcessMemoryDump(session_state)); | 781 new ProcessMemoryDump(session_state)); |
778 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 782 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
779 } | 783 } |
780 return iter->second.get(); | 784 return iter->second.get(); |
781 } | 785 } |
782 | 786 |
783 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer() {} | 787 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer( |
| 788 MemoryDumpManager* mdm) |
| 789 : mdm_(mdm) {} |
784 | 790 |
785 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() { | 791 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() { |
786 Stop(); | 792 Stop(); |
787 } | 793 } |
788 | 794 |
789 void MemoryDumpManager::PeriodicGlobalDumpTimer::Start( | 795 void MemoryDumpManager::PeriodicGlobalDumpTimer::Start( |
790 const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list) { | 796 const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list) { |
791 if (triggers_list.empty()) | 797 if (triggers_list.empty()) |
792 return; | 798 return; |
793 | 799 |
794 // At the moment the periodic support is limited to at most one periodic | 800 // At the moment the periodic support is limited to at most one periodic |
795 // trigger per dump mode. All intervals should be an integer multiple of the | 801 // trigger per dump mode. All intervals should be an integer multiple of the |
796 // smallest interval specified. | 802 // smallest interval specified. |
797 periodic_dumps_count_ = 0; | 803 periodic_dumps_count_ = 0; |
798 uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max(); | 804 uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max(); |
799 uint32_t light_dump_period_ms = 0; | 805 uint32_t light_dump_period_ms = 0; |
800 uint32_t heavy_dump_period_ms = 0; | 806 uint32_t heavy_dump_period_ms = 0; |
801 DCHECK_LE(triggers_list.size(), 3u); | 807 DCHECK_LE(triggers_list.size(), 3u); |
802 for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) { | 808 for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) { |
803 DCHECK_NE(0u, config.periodic_interval_ms); | 809 DCHECK_NE(0u, config.periodic_interval_ms); |
804 if (config.level_of_detail == MemoryDumpLevelOfDetail::LIGHT) { | 810 switch (config.level_of_detail) { |
805 DCHECK_EQ(0u, light_dump_period_ms); | 811 case MemoryDumpLevelOfDetail::BACKGROUND: |
806 light_dump_period_ms = config.periodic_interval_ms; | 812 DCHECK(mdm_->IsDumpModeAllowed(MemoryDumpLevelOfDetail::BACKGROUND)); |
807 } else if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { | 813 break; |
808 DCHECK_EQ(0u, heavy_dump_period_ms); | 814 case MemoryDumpLevelOfDetail::LIGHT: |
809 heavy_dump_period_ms = config.periodic_interval_ms; | 815 DCHECK_EQ(0u, light_dump_period_ms); |
| 816 DCHECK(mdm_->IsDumpModeAllowed(MemoryDumpLevelOfDetail::LIGHT)); |
| 817 light_dump_period_ms = config.periodic_interval_ms; |
| 818 break; |
| 819 case MemoryDumpLevelOfDetail::DETAILED: |
| 820 DCHECK_EQ(0u, heavy_dump_period_ms); |
| 821 DCHECK(mdm_->IsDumpModeAllowed(MemoryDumpLevelOfDetail::DETAILED)); |
| 822 heavy_dump_period_ms = config.periodic_interval_ms; |
| 823 break; |
810 } | 824 } |
811 min_timer_period_ms = | 825 min_timer_period_ms = |
812 std::min(min_timer_period_ms, config.periodic_interval_ms); | 826 std::min(min_timer_period_ms, config.periodic_interval_ms); |
813 } | 827 } |
814 | 828 |
815 DCHECK_EQ(0u, light_dump_period_ms % min_timer_period_ms); | 829 DCHECK_EQ(0u, light_dump_period_ms % min_timer_period_ms); |
816 light_dump_rate_ = light_dump_period_ms / min_timer_period_ms; | 830 light_dump_rate_ = light_dump_period_ms / min_timer_period_ms; |
817 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); | 831 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); |
818 heavy_dump_rate_ = heavy_dump_period_ms / min_timer_period_ms; | 832 heavy_dump_rate_ = heavy_dump_period_ms / min_timer_period_ms; |
819 | 833 |
(...skipping 13 matching lines...) Expand all Loading... |
833 } | 847 } |
834 | 848 |
835 void MemoryDumpManager::PeriodicGlobalDumpTimer::RequestPeriodicGlobalDump() { | 849 void MemoryDumpManager::PeriodicGlobalDumpTimer::RequestPeriodicGlobalDump() { |
836 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND; | 850 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND; |
837 if (light_dump_rate_ > 0 && periodic_dumps_count_ % light_dump_rate_ == 0) | 851 if (light_dump_rate_ > 0 && periodic_dumps_count_ % light_dump_rate_ == 0) |
838 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; | 852 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; |
839 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 853 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
840 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 854 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
841 ++periodic_dumps_count_; | 855 ++periodic_dumps_count_; |
842 | 856 |
843 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 857 mdm_->RequestGlobalDump(MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
844 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | |
845 } | 858 } |
846 | 859 |
847 } // namespace trace_event | 860 } // namespace trace_event |
848 } // namespace base | 861 } // namespace base |
OLD | NEW |