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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 | 124 |
125 // static | 125 // static |
126 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { | 126 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
127 g_instance_for_testing = instance; | 127 g_instance_for_testing = instance; |
128 } | 128 } |
129 | 129 |
130 MemoryDumpManager::MemoryDumpManager() | 130 MemoryDumpManager::MemoryDumpManager() |
131 : delegate_(nullptr), | 131 : delegate_(nullptr), |
132 is_coordinator_(false), | 132 is_coordinator_(false), |
133 memory_tracing_enabled_(0), | 133 memory_tracing_enabled_(0), |
134 periodic_dump_timer_(this), | |
134 tracing_process_id_(kInvalidTracingProcessId), | 135 tracing_process_id_(kInvalidTracingProcessId), |
135 dumper_registrations_ignored_for_testing_(false), | 136 dumper_registrations_ignored_for_testing_(false), |
136 heap_profiling_enabled_(false) { | 137 heap_profiling_enabled_(false) { |
137 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 138 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
138 | 139 |
139 // At this point the command line may not be initialized but we try to | 140 // At this point the command line may not be initialized but we try to |
140 // enable the heap profiler to capture allocations as soon as possible. | 141 // enable the heap profiler to capture allocations as soon as possible. |
141 EnableHeapProfilingIfNeeded(); | 142 EnableHeapProfilingIfNeeded(); |
142 } | 143 } |
143 | 144 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 // to just skip it, without actually invoking the |mdp|, which might be | 329 // to just skip it, without actually invoking the |mdp|, which might be |
329 // destroyed by the caller soon after this method returns. | 330 // destroyed by the caller soon after this method returns. |
330 (*mdp_iter)->disabled = true; | 331 (*mdp_iter)->disabled = true; |
331 dump_providers_.erase(mdp_iter); | 332 dump_providers_.erase(mdp_iter); |
332 } | 333 } |
333 | 334 |
334 void MemoryDumpManager::RequestGlobalDump( | 335 void MemoryDumpManager::RequestGlobalDump( |
335 MemoryDumpType dump_type, | 336 MemoryDumpType dump_type, |
336 MemoryDumpLevelOfDetail level_of_detail, | 337 MemoryDumpLevelOfDetail level_of_detail, |
337 const MemoryDumpCallback& callback) { | 338 const MemoryDumpCallback& callback) { |
338 // Bail out immediately if tracing is not enabled at all. | 339 // Bail out immediately if tracing is not enabled at all or if the dump mode |
339 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) { | 340 // is not allowed. |
341 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_)) || | |
342 !IsDumpModeAllowed(level_of_detail)) { | |
340 VLOG(1) << "Global memory dump failed because " << kTraceCategory | 343 VLOG(1) << "Global memory dump failed because " << kTraceCategory |
341 << " tracing category is not enabled"; | 344 << " tracing category is not enabled or the requested dump mode is " |
345 "not allowed by trace config."; | |
342 if (!callback.is_null()) | 346 if (!callback.is_null()) |
343 callback.Run(0u /* guid */, false /* success */); | 347 callback.Run(0u /* guid */, false /* success */); |
344 return; | 348 return; |
345 } | 349 } |
346 | 350 |
347 const uint64_t guid = | 351 const uint64_t guid = |
348 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); | 352 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); |
349 | 353 |
350 // Creates an async event to keep track of the global dump evolution. | 354 // Creates an async event to keep track of the global dump evolution. |
351 // The |wrapped_callback| will generate the ASYNC_END event and then invoke | 355 // The |wrapped_callback| will generate the ASYNC_END event and then invoke |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
700 session_state_ = nullptr; | 704 session_state_ = nullptr; |
701 } | 705 } |
702 | 706 |
703 // Thread stops are blocking and must be performed outside of the |lock_| | 707 // Thread stops are blocking and must be performed outside of the |lock_| |
704 // or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it). | 708 // or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it). |
705 periodic_dump_timer_.Stop(); | 709 periodic_dump_timer_.Stop(); |
706 if (dump_thread) | 710 if (dump_thread) |
707 dump_thread->Stop(); | 711 dump_thread->Stop(); |
708 } | 712 } |
709 | 713 |
714 bool MemoryDumpManager::IsDumpModeAllowed( | |
715 MemoryDumpLevelOfDetail dump_mode) const { | |
716 return session_state_->memory_dump_config().allowed_dump_modes.count( | |
Primiano Tucci (use gerrit)
2016/06/09 18:46:39
- Take the AutoLock lock(lock_); session_state is
ssid
2016/06/09 21:34:15
Fixed the lock. Also renamed the session_state get
| |
717 dump_mode) != 0; | |
718 } | |
719 | |
710 uint64_t MemoryDumpManager::GetTracingProcessId() const { | 720 uint64_t MemoryDumpManager::GetTracingProcessId() const { |
711 return delegate_->GetTracingProcessId(); | 721 return delegate_->GetTracingProcessId(); |
712 } | 722 } |
713 | 723 |
714 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo( | 724 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo( |
715 MemoryDumpProvider* dump_provider, | 725 MemoryDumpProvider* dump_provider, |
716 const char* name, | 726 const char* name, |
717 scoped_refptr<SequencedTaskRunner> task_runner, | 727 scoped_refptr<SequencedTaskRunner> task_runner, |
718 const MemoryDumpProvider::Options& options, | 728 const MemoryDumpProvider::Options& options, |
719 bool whitelisted_for_background_mode) | 729 bool whitelisted_for_background_mode) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
763 const MemoryDumpArgs& dump_args) { | 773 const MemoryDumpArgs& dump_args) { |
764 auto iter = process_dumps.find(pid); | 774 auto iter = process_dumps.find(pid); |
765 if (iter == process_dumps.end()) { | 775 if (iter == process_dumps.end()) { |
766 std::unique_ptr<ProcessMemoryDump> new_pmd( | 776 std::unique_ptr<ProcessMemoryDump> new_pmd( |
767 new ProcessMemoryDump(session_state, dump_args)); | 777 new ProcessMemoryDump(session_state, dump_args)); |
768 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 778 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
769 } | 779 } |
770 return iter->second.get(); | 780 return iter->second.get(); |
771 } | 781 } |
772 | 782 |
773 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer() {} | 783 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer( |
784 MemoryDumpManager* mdm) | |
785 : mdm_(mdm) {} | |
774 | 786 |
775 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() { | 787 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() { |
776 Stop(); | 788 Stop(); |
777 } | 789 } |
778 | 790 |
779 void MemoryDumpManager::PeriodicGlobalDumpTimer::Start( | 791 void MemoryDumpManager::PeriodicGlobalDumpTimer::Start( |
780 const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list) { | 792 const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list) { |
781 if (triggers_list.empty()) | 793 if (triggers_list.empty()) |
782 return; | 794 return; |
783 | 795 |
784 // At the moment the periodic support is limited to at most one periodic | 796 // At the moment the periodic support is limited to at most one periodic |
785 // trigger per dump mode. All intervals should be an integer multiple of the | 797 // trigger per dump mode. All intervals should be an integer multiple of the |
786 // smallest interval specified. | 798 // smallest interval specified. |
787 periodic_dumps_count_ = 0; | 799 periodic_dumps_count_ = 0; |
788 uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max(); | 800 uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max(); |
789 uint32_t light_dump_period_ms = 0; | 801 uint32_t light_dump_period_ms = 0; |
790 uint32_t heavy_dump_period_ms = 0; | 802 uint32_t heavy_dump_period_ms = 0; |
791 DCHECK_LE(triggers_list.size(), 3u); | 803 DCHECK_LE(triggers_list.size(), 3u); |
792 for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) { | 804 for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) { |
793 DCHECK_NE(0u, config.periodic_interval_ms); | 805 DCHECK_NE(0u, config.periodic_interval_ms); |
794 if (config.level_of_detail == MemoryDumpLevelOfDetail::LIGHT) { | 806 switch (config.level_of_detail) { |
795 DCHECK_EQ(0u, light_dump_period_ms); | 807 case MemoryDumpLevelOfDetail::BACKGROUND: |
796 light_dump_period_ms = config.periodic_interval_ms; | 808 DCHECK(mdm_->IsDumpModeAllowed(MemoryDumpLevelOfDetail::BACKGROUND)); |
797 } else if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { | 809 break; |
798 DCHECK_EQ(0u, heavy_dump_period_ms); | 810 case MemoryDumpLevelOfDetail::LIGHT: |
799 heavy_dump_period_ms = config.periodic_interval_ms; | 811 DCHECK_EQ(0u, light_dump_period_ms); |
812 DCHECK(mdm_->IsDumpModeAllowed(MemoryDumpLevelOfDetail::LIGHT)); | |
813 light_dump_period_ms = config.periodic_interval_ms; | |
814 break; | |
815 case MemoryDumpLevelOfDetail::DETAILED: | |
816 DCHECK_EQ(0u, heavy_dump_period_ms); | |
817 DCHECK(mdm_->IsDumpModeAllowed(MemoryDumpLevelOfDetail::DETAILED)); | |
818 heavy_dump_period_ms = config.periodic_interval_ms; | |
819 break; | |
800 } | 820 } |
801 min_timer_period_ms = | 821 min_timer_period_ms = |
802 std::min(min_timer_period_ms, config.periodic_interval_ms); | 822 std::min(min_timer_period_ms, config.periodic_interval_ms); |
803 } | 823 } |
804 | 824 |
805 DCHECK_EQ(0u, light_dump_period_ms % min_timer_period_ms); | 825 DCHECK_EQ(0u, light_dump_period_ms % min_timer_period_ms); |
806 light_dump_rate_ = light_dump_period_ms / min_timer_period_ms; | 826 light_dump_rate_ = light_dump_period_ms / min_timer_period_ms; |
807 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); | 827 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); |
808 heavy_dump_rate_ = heavy_dump_period_ms / min_timer_period_ms; | 828 heavy_dump_rate_ = heavy_dump_period_ms / min_timer_period_ms; |
809 | 829 |
(...skipping 13 matching lines...) Expand all Loading... | |
823 } | 843 } |
824 | 844 |
825 void MemoryDumpManager::PeriodicGlobalDumpTimer::RequestPeriodicGlobalDump() { | 845 void MemoryDumpManager::PeriodicGlobalDumpTimer::RequestPeriodicGlobalDump() { |
826 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND; | 846 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND; |
827 if (light_dump_rate_ > 0 && periodic_dumps_count_ % light_dump_rate_ == 0) | 847 if (light_dump_rate_ > 0 && periodic_dumps_count_ % light_dump_rate_ == 0) |
828 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; | 848 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; |
829 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 849 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
830 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 850 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
831 ++periodic_dumps_count_; | 851 ++periodic_dumps_count_; |
832 | 852 |
833 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 853 mdm_->RequestGlobalDump(MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
834 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | |
835 } | 854 } |
836 | 855 |
837 } // namespace trace_event | 856 } // namespace trace_event |
838 } // namespace base | 857 } // namespace base |
OLD | NEW |