| 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 |