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 <inttypes.h> | 7 #include <inttypes.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 return Singleton<MemoryDumpManager, | 177 return Singleton<MemoryDumpManager, |
178 LeakySingletonTraits<MemoryDumpManager>>::get(); | 178 LeakySingletonTraits<MemoryDumpManager>>::get(); |
179 } | 179 } |
180 | 180 |
181 // static | 181 // static |
182 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { | 182 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
183 g_instance_for_testing = instance; | 183 g_instance_for_testing = instance; |
184 } | 184 } |
185 | 185 |
186 MemoryDumpManager::MemoryDumpManager() | 186 MemoryDumpManager::MemoryDumpManager() |
187 : memory_tracing_enabled_(0), | 187 : is_coordinator_(false), |
| 188 memory_tracing_enabled_(0), |
188 tracing_process_id_(kInvalidTracingProcessId), | 189 tracing_process_id_(kInvalidTracingProcessId), |
189 dumper_registrations_ignored_for_testing_(false), | 190 dumper_registrations_ignored_for_testing_(false), |
190 heap_profiling_enabled_(false) { | 191 heap_profiling_enabled_(false) { |
191 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 192 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
192 | 193 |
193 // At this point the command line may not be initialized but we try to | 194 // At this point the command line may not be initialized but we try to |
194 // enable the heap profiler to capture allocations as soon as possible. | 195 // enable the heap profiler to capture allocations as soon as possible. |
195 EnableHeapProfilingIfNeeded(); | 196 EnableHeapProfilingIfNeeded(); |
196 | 197 |
197 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), | 198 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 CHECK(false) << "Invalid mode '" << profiling_mode << "' for " | 235 CHECK(false) << "Invalid mode '" << profiling_mode << "' for " |
235 << switches::kEnableHeapProfiling << " flag."; | 236 << switches::kEnableHeapProfiling << " flag."; |
236 } | 237 } |
237 | 238 |
238 for (auto mdp : dump_providers_) | 239 for (auto mdp : dump_providers_) |
239 mdp->dump_provider->OnHeapProfilingEnabled(true); | 240 mdp->dump_provider->OnHeapProfilingEnabled(true); |
240 heap_profiling_enabled_ = true; | 241 heap_profiling_enabled_ = true; |
241 } | 242 } |
242 | 243 |
243 void MemoryDumpManager::Initialize( | 244 void MemoryDumpManager::Initialize( |
244 std::unique_ptr<MemoryDumpManagerDelegate> delegate) { | 245 RequestGlobalDumpCallback request_dump_callback, |
| 246 bool is_coordinator) { |
245 { | 247 { |
246 AutoLock lock(lock_); | 248 AutoLock lock(lock_); |
247 DCHECK(delegate); | 249 DCHECK(!request_dump_callback.is_null()); |
248 DCHECK(!delegate_); | 250 DCHECK(request_dump_callback_.is_null()); |
249 delegate_ = std::move(delegate); | 251 request_dump_callback_ = request_dump_callback; |
| 252 is_coordinator_ = is_coordinator; |
250 EnableHeapProfilingIfNeeded(); | 253 EnableHeapProfilingIfNeeded(); |
251 } | 254 } |
252 | 255 |
253 // Enable the core dump providers. | 256 // Enable the core dump providers. |
254 #if defined(MALLOC_MEMORY_TRACING_SUPPORTED) | 257 #if defined(MALLOC_MEMORY_TRACING_SUPPORTED) |
255 RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); | 258 RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr); |
256 #endif | 259 #endif |
257 | 260 |
258 #if defined(OS_ANDROID) | 261 #if defined(OS_ANDROID) |
259 RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap", | 262 RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap", |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 461 |
459 // Creates an async event to keep track of the global dump evolution. | 462 // Creates an async event to keep track of the global dump evolution. |
460 // The |wrapped_callback| will generate the ASYNC_END event and then invoke | 463 // The |wrapped_callback| will generate the ASYNC_END event and then invoke |
461 // the real |callback| provided by the caller. | 464 // the real |callback| provided by the caller. |
462 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( | 465 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( |
463 kTraceCategory, "GlobalMemoryDump", TRACE_ID_LOCAL(guid), "dump_type", | 466 kTraceCategory, "GlobalMemoryDump", TRACE_ID_LOCAL(guid), "dump_type", |
464 MemoryDumpTypeToString(dump_type), "level_of_detail", | 467 MemoryDumpTypeToString(dump_type), "level_of_detail", |
465 MemoryDumpLevelOfDetailToString(level_of_detail)); | 468 MemoryDumpLevelOfDetailToString(level_of_detail)); |
466 GlobalMemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback); | 469 GlobalMemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback); |
467 | 470 |
468 // The delegate will coordinate the IPC broadcast and at some point invoke | 471 // The embedder will coordinate the IPC broadcast and at some point invoke |
469 // CreateProcessDump() to get a dump for the current process. | 472 // CreateProcessDump() to get a dump for the current process. |
470 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail}; | 473 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail}; |
471 delegate_->RequestGlobalMemoryDump(args, wrapped_callback); | 474 request_dump_callback_.Run(args, wrapped_callback); |
472 } | 475 } |
473 | 476 |
474 void MemoryDumpManager::GetDumpProvidersForPolling( | 477 void MemoryDumpManager::GetDumpProvidersForPolling( |
475 std::vector<scoped_refptr<MemoryDumpProviderInfo>>* providers) { | 478 std::vector<scoped_refptr<MemoryDumpProviderInfo>>* providers) { |
476 DCHECK(providers->empty()); | 479 DCHECK(providers->empty()); |
477 AutoLock lock(lock_); | 480 AutoLock lock(lock_); |
478 for (const scoped_refptr<MemoryDumpProviderInfo>& mdp : dump_providers_) { | 481 for (const scoped_refptr<MemoryDumpProviderInfo>& mdp : dump_providers_) { |
479 if (mdp->options.is_fast_polling_supported) | 482 if (mdp->options.is_fast_polling_supported) |
480 providers->push_back(mdp); | 483 providers->push_back(mdp); |
481 } | 484 } |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 | 861 |
859 TRACE_EVENT_API_ADD_METADATA_EVENT( | 862 TRACE_EVENT_API_ADD_METADATA_EVENT( |
860 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", | 863 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", |
861 "typeNames", | 864 "typeNames", |
862 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( | 865 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( |
863 session_state, &MemoryDumpSessionState::type_name_deduplicator)); | 866 session_state, &MemoryDumpSessionState::type_name_deduplicator)); |
864 } | 867 } |
865 | 868 |
866 AutoLock lock(lock_); | 869 AutoLock lock(lock_); |
867 | 870 |
868 DCHECK(delegate_); // At this point we must have a delegate. | 871 // At this point we must have the ability to request global dumps. |
| 872 DCHECK(!request_dump_callback_.is_null()); |
869 session_state_ = session_state; | 873 session_state_ = session_state; |
870 | 874 |
871 DCHECK(!dump_thread_); | 875 DCHECK(!dump_thread_); |
872 dump_thread_ = std::move(dump_thread); | 876 dump_thread_ = std::move(dump_thread); |
873 | 877 |
874 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); | 878 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
875 | 879 |
876 MemoryDumpScheduler::Config periodic_config; | 880 MemoryDumpScheduler::Config periodic_config; |
877 bool peak_detector_configured = false; | 881 bool peak_detector_configured = false; |
878 for (const auto& trigger : memory_dump_config.triggers) { | 882 for (const auto& trigger : memory_dump_config.triggers) { |
(...skipping 19 matching lines...) Expand all Loading... |
898 | 902 |
899 MemoryPeakDetector::Config peak_config; | 903 MemoryPeakDetector::Config peak_config; |
900 peak_config.polling_interval_ms = 10; | 904 peak_config.polling_interval_ms = 10; |
901 peak_config.min_time_between_peaks_ms = trigger.min_time_between_dumps_ms; | 905 peak_config.min_time_between_peaks_ms = trigger.min_time_between_dumps_ms; |
902 peak_config.enable_verbose_poll_tracing = | 906 peak_config.enable_verbose_poll_tracing = |
903 trigger.level_of_detail == MemoryDumpLevelOfDetail::DETAILED; | 907 trigger.level_of_detail == MemoryDumpLevelOfDetail::DETAILED; |
904 MemoryPeakDetector::GetInstance()->Start(peak_config); | 908 MemoryPeakDetector::GetInstance()->Start(peak_config); |
905 | 909 |
906 // When peak detection is enabled, trigger a dump straight away as it | 910 // When peak detection is enabled, trigger a dump straight away as it |
907 // gives a good reference point for analyzing the trace. | 911 // gives a good reference point for analyzing the trace. |
908 if (delegate_->IsCoordinator()) { | 912 if (is_coordinator_) { |
909 dump_thread_->task_runner()->PostTask( | 913 dump_thread_->task_runner()->PostTask( |
910 FROM_HERE, BindRepeating(&OnPeakDetected, trigger.level_of_detail)); | 914 FROM_HERE, BindRepeating(&OnPeakDetected, trigger.level_of_detail)); |
911 } | 915 } |
912 } | 916 } |
913 } | 917 } |
914 | 918 |
915 // Only coordinator process triggers periodic global memory dumps. | 919 // Only coordinator process triggers periodic global memory dumps. |
916 if (delegate_->IsCoordinator() && !periodic_config.triggers.empty()) { | 920 if (is_coordinator_ && !periodic_config.triggers.empty()) { |
917 MemoryDumpScheduler::GetInstance()->Start(periodic_config, | 921 MemoryDumpScheduler::GetInstance()->Start(periodic_config, |
918 dump_thread_->task_runner()); | 922 dump_thread_->task_runner()); |
919 } | 923 } |
920 } | 924 } |
921 | 925 |
922 void MemoryDumpManager::OnTraceLogDisabled() { | 926 void MemoryDumpManager::OnTraceLogDisabled() { |
923 // There might be a memory dump in progress while this happens. Therefore, | 927 // There might be a memory dump in progress while this happens. Therefore, |
924 // ensure that the MDM state which depends on the tracing enabled / disabled | 928 // ensure that the MDM state which depends on the tracing enabled / disabled |
925 // state is always accessed by the dumping methods holding the |lock_|. | 929 // state is always accessed by the dumping methods holding the |lock_|. |
926 if (!subtle::NoBarrier_Load(&memory_tracing_enabled_)) | 930 if (!subtle::NoBarrier_Load(&memory_tracing_enabled_)) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 if (iter == process_dumps.end()) { | 978 if (iter == process_dumps.end()) { |
975 std::unique_ptr<ProcessMemoryDump> new_pmd( | 979 std::unique_ptr<ProcessMemoryDump> new_pmd( |
976 new ProcessMemoryDump(session_state, dump_args)); | 980 new ProcessMemoryDump(session_state, dump_args)); |
977 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 981 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
978 } | 982 } |
979 return iter->second.get(); | 983 return iter->second.get(); |
980 } | 984 } |
981 | 985 |
982 } // namespace trace_event | 986 } // namespace trace_event |
983 } // namespace base | 987 } // namespace base |
OLD | NEW |