| 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/allocator/features.h" | 10 #include "base/allocator/features.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 return Singleton<MemoryDumpManager, | 145 return Singleton<MemoryDumpManager, |
| 146 LeakySingletonTraits<MemoryDumpManager>>::get(); | 146 LeakySingletonTraits<MemoryDumpManager>>::get(); |
| 147 } | 147 } |
| 148 | 148 |
| 149 // static | 149 // static |
| 150 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { | 150 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
| 151 g_instance_for_testing = instance; | 151 g_instance_for_testing = instance; |
| 152 } | 152 } |
| 153 | 153 |
| 154 MemoryDumpManager::MemoryDumpManager() | 154 MemoryDumpManager::MemoryDumpManager() |
| 155 : delegate_(nullptr), | 155 : memory_tracing_enabled_(0), |
| 156 is_coordinator_(false), | |
| 157 memory_tracing_enabled_(0), | |
| 158 tracing_process_id_(kInvalidTracingProcessId), | 156 tracing_process_id_(kInvalidTracingProcessId), |
| 159 dumper_registrations_ignored_for_testing_(false), | 157 dumper_registrations_ignored_for_testing_(false), |
| 160 heap_profiling_enabled_(false) { | 158 heap_profiling_enabled_(false) { |
| 161 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 159 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
| 162 | 160 |
| 163 // At this point the command line may not be initialized but we try to | 161 // At this point the command line may not be initialized but we try to |
| 164 // enable the heap profiler to capture allocations as soon as possible. | 162 // enable the heap profiler to capture allocations as soon as possible. |
| 165 EnableHeapProfilingIfNeeded(); | 163 EnableHeapProfilingIfNeeded(); |
| 166 | 164 |
| 167 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), | 165 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } else { | 200 } else { |
| 203 CHECK(false) << "Invalid mode '" << profiling_mode << "' for " | 201 CHECK(false) << "Invalid mode '" << profiling_mode << "' for " |
| 204 << switches::kEnableHeapProfiling << " flag."; | 202 << switches::kEnableHeapProfiling << " flag."; |
| 205 } | 203 } |
| 206 | 204 |
| 207 for (auto mdp : dump_providers_) | 205 for (auto mdp : dump_providers_) |
| 208 mdp->dump_provider->OnHeapProfilingEnabled(true); | 206 mdp->dump_provider->OnHeapProfilingEnabled(true); |
| 209 heap_profiling_enabled_ = true; | 207 heap_profiling_enabled_ = true; |
| 210 } | 208 } |
| 211 | 209 |
| 212 void MemoryDumpManager::Initialize(MemoryDumpManagerDelegate* delegate, | 210 void MemoryDumpManager::Initialize( |
| 213 bool is_coordinator) { | 211 std::unique_ptr<MemoryDumpManagerDelegate> delegate) { |
| 214 { | 212 { |
| 215 AutoLock lock(lock_); | 213 AutoLock lock(lock_); |
| 216 DCHECK(delegate); | 214 DCHECK(delegate); |
| 217 DCHECK(!delegate_); | 215 DCHECK(!delegate_); |
| 218 delegate_ = delegate; | 216 delegate_.swap(delegate); |
| 219 is_coordinator_ = is_coordinator; | |
| 220 EnableHeapProfilingIfNeeded(); | 217 EnableHeapProfilingIfNeeded(); |
| 221 } | 218 } |
| 222 | 219 |
| 223 // Enable the core dump providers. | 220 // Enable the core dump providers. |
| 224 #if defined(MALLOC_MEMORY_TRACING_SUPPORTED) | 221 #if defined(MALLOC_MEMORY_TRACING_SUPPORTED) |
| 225 RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); | 222 RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); |
| 226 #endif | 223 #endif |
| 227 | 224 |
| 228 #if defined(OS_ANDROID) | 225 #if defined(OS_ANDROID) |
| 229 RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap", | 226 RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap", |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 const uint64_t guid = | 437 const uint64_t guid = |
| 441 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); | 438 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); |
| 442 | 439 |
| 443 // Creates an async event to keep track of the global dump evolution. | 440 // Creates an async event to keep track of the global dump evolution. |
| 444 // The |wrapped_callback| will generate the ASYNC_END event and then invoke | 441 // The |wrapped_callback| will generate the ASYNC_END event and then invoke |
| 445 // the real |callback| provided by the caller. | 442 // the real |callback| provided by the caller. |
| 446 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(kTraceCategory, "GlobalMemoryDump", | 443 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(kTraceCategory, "GlobalMemoryDump", |
| 447 TRACE_ID_MANGLE(guid)); | 444 TRACE_ID_MANGLE(guid)); |
| 448 MemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback); | 445 MemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback); |
| 449 | 446 |
| 450 // Technically there is no need to grab the |lock_| here as the delegate is | |
| 451 // long-lived and can only be set by Initialize(), which is locked and | |
| 452 // necessarily happens before memory_tracing_enabled_ == true. | |
| 453 // Not taking the |lock_|, though, is lakely make TSan barf and, at this point | |
| 454 // (memory-infra is enabled) we're not in the fast-path anymore. | |
| 455 MemoryDumpManagerDelegate* delegate; | |
| 456 { | |
| 457 AutoLock lock(lock_); | |
| 458 delegate = delegate_; | |
| 459 } | |
| 460 | |
| 461 // The delegate will coordinate the IPC broadcast and at some point invoke | 447 // The delegate will coordinate the IPC broadcast and at some point invoke |
| 462 // CreateProcessDump() to get a dump for the current process. | 448 // CreateProcessDump() to get a dump for the current process. |
| 463 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail}; | 449 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail}; |
| 464 delegate->RequestGlobalMemoryDump(args, wrapped_callback); | 450 delegate_->RequestGlobalMemoryDump(args, wrapped_callback); |
| 465 } | 451 } |
| 466 | 452 |
| 467 void MemoryDumpManager::RequestGlobalDump( | 453 void MemoryDumpManager::RequestGlobalDump( |
| 468 MemoryDumpType dump_type, | 454 MemoryDumpType dump_type, |
| 469 MemoryDumpLevelOfDetail level_of_detail) { | 455 MemoryDumpLevelOfDetail level_of_detail) { |
| 470 RequestGlobalDump(dump_type, level_of_detail, MemoryDumpCallback()); | 456 RequestGlobalDump(dump_type, level_of_detail, MemoryDumpCallback()); |
| 471 } | 457 } |
| 472 | 458 |
| 473 void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, | 459 void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, |
| 474 const MemoryDumpCallback& callback) { | 460 const MemoryDumpCallback& callback) { |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 dump_thread_ = std::move(dump_thread); | 786 dump_thread_ = std::move(dump_thread); |
| 801 | 787 |
| 802 dump_providers_for_polling_.clear(); | 788 dump_providers_for_polling_.clear(); |
| 803 for (const auto& mdpinfo : dump_providers_) { | 789 for (const auto& mdpinfo : dump_providers_) { |
| 804 if (mdpinfo->options.is_fast_polling_supported) | 790 if (mdpinfo->options.is_fast_polling_supported) |
| 805 dump_providers_for_polling_.insert(mdpinfo); | 791 dump_providers_for_polling_.insert(mdpinfo); |
| 806 } | 792 } |
| 807 | 793 |
| 808 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); | 794 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
| 809 | 795 |
| 810 if (!is_coordinator_) | 796 if (!delegate_->IsCoordinator()) |
| 811 return; | 797 return; |
| 812 } | 798 } |
| 813 | 799 |
| 814 // Enable periodic dumps if necessary. | 800 // Enable periodic dumps if necessary. |
| 815 periodic_dump_timer_.Start(trace_config.memory_dump_config().triggers); | 801 periodic_dump_timer_.Start(trace_config.memory_dump_config().triggers); |
| 816 } | 802 } |
| 817 | 803 |
| 818 void MemoryDumpManager::OnTraceLogDisabled() { | 804 void MemoryDumpManager::OnTraceLogDisabled() { |
| 819 // There might be a memory dump in progress while this happens. Therefore, | 805 // There might be a memory dump in progress while this happens. Therefore, |
| 820 // ensure that the MDM state which depends on the tracing enabled / disabled | 806 // ensure that the MDM state which depends on the tracing enabled / disabled |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 972 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
| 987 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 973 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
| 988 ++periodic_dumps_count_; | 974 ++periodic_dumps_count_; |
| 989 | 975 |
| 990 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 976 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
| 991 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | 977 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
| 992 } | 978 } |
| 993 | 979 |
| 994 } // namespace trace_event | 980 } // namespace trace_event |
| 995 } // namespace base | 981 } // namespace base |
| OLD | NEW |