Chromium Code Reviews| 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 |