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" |
11 #include "base/base_switches.h" | 11 #include "base/base_switches.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/debug/debugging_flags.h" | 14 #include "base/debug/debugging_flags.h" |
15 #include "base/debug/stack_trace.h" | 15 #include "base/debug/stack_trace.h" |
16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
17 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
19 #include "base/timer/timer.h" | |
20 #include "base/trace_event/heap_profiler.h" | 19 #include "base/trace_event/heap_profiler.h" |
21 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 20 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
22 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" | 21 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" |
23 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" | 22 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" |
24 #include "base/trace_event/malloc_dump_provider.h" | 23 #include "base/trace_event/malloc_dump_provider.h" |
25 #include "base/trace_event/memory_dump_provider.h" | 24 #include "base/trace_event/memory_dump_provider.h" |
26 #include "base/trace_event/memory_dump_session_state.h" | 25 #include "base/trace_event/memory_dump_session_state.h" |
| 26 #include "base/trace_event/memory_infra_background_whitelist.h" |
27 #include "base/trace_event/process_memory_dump.h" | 27 #include "base/trace_event/process_memory_dump.h" |
28 #include "base/trace_event/trace_event.h" | 28 #include "base/trace_event/trace_event.h" |
29 #include "base/trace_event/trace_event_argument.h" | 29 #include "base/trace_event/trace_event_argument.h" |
30 #include "build/build_config.h" | 30 #include "build/build_config.h" |
31 | 31 |
32 #if defined(OS_ANDROID) | 32 #if defined(OS_ANDROID) |
33 #include "base/trace_event/java_heap_dump_provider_android.h" | 33 #include "base/trace_event/java_heap_dump_provider_android.h" |
34 #endif | 34 #endif |
35 | 35 |
36 #if defined(OS_WIN) | 36 #if defined(OS_WIN) |
37 #include "base/trace_event/winheap_dump_provider_win.h" | 37 #include "base/trace_event/winheap_dump_provider_win.h" |
38 #endif | 38 #endif |
39 | 39 |
40 namespace base { | 40 namespace base { |
41 namespace trace_event { | 41 namespace trace_event { |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 const int kTraceEventNumArgs = 1; | 45 const int kTraceEventNumArgs = 1; |
46 const char* kTraceEventArgNames[] = {"dumps"}; | 46 const char* kTraceEventArgNames[] = {"dumps"}; |
47 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | 47 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; |
48 | 48 |
49 StaticAtomicSequenceNumber g_next_guid; | 49 StaticAtomicSequenceNumber g_next_guid; |
50 MemoryDumpManager* g_instance_for_testing = nullptr; | 50 MemoryDumpManager* g_instance_for_testing = nullptr; |
51 | 51 |
52 // The names of dump providers whitelisted for background tracing. Dump | |
53 // providers can be added here only if the background mode dump has very | |
54 // less performance and memory overhead. | |
55 const char* const kDumpProviderWhitelist[] = { | |
56 // TODO(ssid): Fill this list with dump provider names which support | |
57 // background mode, crbug.com/613198. | |
58 nullptr, // End of list marker. | |
59 }; | |
60 | |
61 // Callback wrapper to hook upon the completion of RequestGlobalDump() and | 52 // Callback wrapper to hook upon the completion of RequestGlobalDump() and |
62 // inject trace markers. | 53 // inject trace markers. |
63 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback, | 54 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback, |
64 uint64_t dump_guid, | 55 uint64_t dump_guid, |
65 bool success) { | 56 bool success) { |
66 TRACE_EVENT_NESTABLE_ASYNC_END1( | 57 TRACE_EVENT_NESTABLE_ASYNC_END1( |
67 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", | 58 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", |
68 TRACE_ID_MANGLE(dump_guid), "success", success); | 59 TRACE_ID_MANGLE(dump_guid), "success", success); |
69 | 60 |
70 if (!wrapped_callback.is_null()) { | 61 if (!wrapped_callback.is_null()) { |
(...skipping 22 matching lines...) Expand all Loading... |
93 void EstimateTraceMemoryOverhead( | 84 void EstimateTraceMemoryOverhead( |
94 TraceEventMemoryOverhead* overhead) override { | 85 TraceEventMemoryOverhead* overhead) override { |
95 return (session_state.get()->*getter_function)() | 86 return (session_state.get()->*getter_function)() |
96 ->EstimateTraceMemoryOverhead(overhead); | 87 ->EstimateTraceMemoryOverhead(overhead); |
97 } | 88 } |
98 | 89 |
99 scoped_refptr<MemoryDumpSessionState> session_state; | 90 scoped_refptr<MemoryDumpSessionState> session_state; |
100 GetterFunctPtr const getter_function; | 91 GetterFunctPtr const getter_function; |
101 }; | 92 }; |
102 | 93 |
103 // Checks if the name is in the given |list|. Last element of the list should be | |
104 // an empty string. | |
105 bool IsNameInList(const char* name, const char* const* list) { | |
106 for (size_t i = 0; list[i] != nullptr; ++i) { | |
107 if (strcmp(name, list[i]) == 0) | |
108 return true; | |
109 } | |
110 return false; | |
111 } | |
112 | |
113 } // namespace | 94 } // namespace |
114 | 95 |
115 // static | 96 // static |
116 const char* const MemoryDumpManager::kTraceCategory = | 97 const char* const MemoryDumpManager::kTraceCategory = |
117 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 98 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
118 | 99 |
119 // static | 100 // static |
120 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; | 101 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; |
121 | 102 |
122 // static | 103 // static |
(...skipping 20 matching lines...) Expand all Loading... |
143 | 124 |
144 // static | 125 // static |
145 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { | 126 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
146 g_instance_for_testing = instance; | 127 g_instance_for_testing = instance; |
147 } | 128 } |
148 | 129 |
149 MemoryDumpManager::MemoryDumpManager() | 130 MemoryDumpManager::MemoryDumpManager() |
150 : delegate_(nullptr), | 131 : delegate_(nullptr), |
151 is_coordinator_(false), | 132 is_coordinator_(false), |
152 memory_tracing_enabled_(0), | 133 memory_tracing_enabled_(0), |
153 dump_provider_whitelist_(kDumpProviderWhitelist), | |
154 tracing_process_id_(kInvalidTracingProcessId), | 134 tracing_process_id_(kInvalidTracingProcessId), |
155 dumper_registrations_ignored_for_testing_(false), | 135 dumper_registrations_ignored_for_testing_(false), |
156 heap_profiling_enabled_(false) { | 136 heap_profiling_enabled_(false) { |
157 g_next_guid.GetNext(); // Make sure that first guid is not zero. | 137 g_next_guid.GetNext(); // Make sure that first guid is not zero. |
158 | 138 |
159 // At this point the command line may not be initialized but we try to | 139 // 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. | 140 // enable the heap profiler to capture allocations as soon as possible. |
161 EnableHeapProfilingIfNeeded(); | 141 EnableHeapProfilingIfNeeded(); |
162 } | 142 } |
163 | 143 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 } | 247 } |
268 | 248 |
269 void MemoryDumpManager::RegisterDumpProviderInternal( | 249 void MemoryDumpManager::RegisterDumpProviderInternal( |
270 MemoryDumpProvider* mdp, | 250 MemoryDumpProvider* mdp, |
271 const char* name, | 251 const char* name, |
272 scoped_refptr<SequencedTaskRunner> task_runner, | 252 scoped_refptr<SequencedTaskRunner> task_runner, |
273 const MemoryDumpProvider::Options& options) { | 253 const MemoryDumpProvider::Options& options) { |
274 if (dumper_registrations_ignored_for_testing_) | 254 if (dumper_registrations_ignored_for_testing_) |
275 return; | 255 return; |
276 | 256 |
277 bool whitelisted_for_background_mode = | 257 bool whitelisted_for_background_mode = IsMemoryDumpProviderWhitelisted(name); |
278 IsNameInList(name, dump_provider_whitelist_); | |
279 scoped_refptr<MemoryDumpProviderInfo> mdpinfo = | 258 scoped_refptr<MemoryDumpProviderInfo> mdpinfo = |
280 new MemoryDumpProviderInfo(mdp, name, std::move(task_runner), options, | 259 new MemoryDumpProviderInfo(mdp, name, std::move(task_runner), options, |
281 whitelisted_for_background_mode); | 260 whitelisted_for_background_mode); |
282 | 261 |
283 { | 262 { |
284 AutoLock lock(lock_); | 263 AutoLock lock(lock_); |
285 bool already_registered = !dump_providers_.insert(mdpinfo).second; | 264 bool already_registered = !dump_providers_.insert(mdpinfo).second; |
286 // This actually happens in some tests which don't have a clean tear-down | 265 // This actually happens in some tests which don't have a clean tear-down |
287 // path for RenderThreadImpl::Init(). | 266 // path for RenderThreadImpl::Init(). |
288 if (already_registered) | 267 if (already_registered) |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 TRACE_EVENT_WITH_FLOW1(kTraceCategory, | 533 TRACE_EVENT_WITH_FLOW1(kTraceCategory, |
555 "MemoryDumpManager::InvokeOnMemoryDump", | 534 "MemoryDumpManager::InvokeOnMemoryDump", |
556 TRACE_ID_MANGLE(pmd_async_state->req_args.dump_guid), | 535 TRACE_ID_MANGLE(pmd_async_state->req_args.dump_guid), |
557 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, | 536 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, |
558 "dump_provider.name", mdpinfo->name); | 537 "dump_provider.name", mdpinfo->name); |
559 | 538 |
560 // Pid of the target process being dumped. Often kNullProcessId (= current | 539 // Pid of the target process being dumped. Often kNullProcessId (= current |
561 // process), non-zero when the coordinator process creates dumps on behalf | 540 // process), non-zero when the coordinator process creates dumps on behalf |
562 // of child processes (see crbug.com/461788). | 541 // of child processes (see crbug.com/461788). |
563 ProcessId target_pid = mdpinfo->options.target_pid; | 542 ProcessId target_pid = mdpinfo->options.target_pid; |
| 543 MemoryDumpArgs args = {pmd_async_state->req_args.level_of_detail}; |
564 ProcessMemoryDump* pmd = | 544 ProcessMemoryDump* pmd = |
565 pmd_async_state->GetOrCreateMemoryDumpContainerForProcess(target_pid); | 545 pmd_async_state->GetOrCreateMemoryDumpContainerForProcess(target_pid, |
566 MemoryDumpArgs args = {pmd_async_state->req_args.level_of_detail}; | 546 args); |
567 bool dump_successful = mdpinfo->dump_provider->OnMemoryDump(args, pmd); | 547 bool dump_successful = mdpinfo->dump_provider->OnMemoryDump(args, pmd); |
568 mdpinfo->consecutive_failures = | 548 mdpinfo->consecutive_failures = |
569 dump_successful ? 0 : mdpinfo->consecutive_failures + 1; | 549 dump_successful ? 0 : mdpinfo->consecutive_failures + 1; |
570 } | 550 } |
571 | 551 |
572 pmd_async_state->pending_dump_providers.pop_back(); | 552 pmd_async_state->pending_dump_providers.pop_back(); |
573 SetupNextMemoryDump(std::move(pmd_async_state)); | 553 SetupNextMemoryDump(std::move(pmd_async_state)); |
574 } | 554 } |
575 | 555 |
576 // static | 556 // static |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 callback_task_runner(MessageLoop::current()->task_runner()), | 743 callback_task_runner(MessageLoop::current()->task_runner()), |
764 dump_thread_task_runner(std::move(dump_thread_task_runner)) { | 744 dump_thread_task_runner(std::move(dump_thread_task_runner)) { |
765 pending_dump_providers.reserve(dump_providers.size()); | 745 pending_dump_providers.reserve(dump_providers.size()); |
766 pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend()); | 746 pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend()); |
767 } | 747 } |
768 | 748 |
769 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { | 749 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { |
770 } | 750 } |
771 | 751 |
772 ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState:: | 752 ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState:: |
773 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid) { | 753 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid, |
| 754 const MemoryDumpArgs& dump_args) { |
774 auto iter = process_dumps.find(pid); | 755 auto iter = process_dumps.find(pid); |
775 if (iter == process_dumps.end()) { | 756 if (iter == process_dumps.end()) { |
776 std::unique_ptr<ProcessMemoryDump> new_pmd( | 757 std::unique_ptr<ProcessMemoryDump> new_pmd( |
777 new ProcessMemoryDump(session_state)); | 758 new ProcessMemoryDump(session_state, dump_args)); |
778 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 759 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
779 } | 760 } |
780 return iter->second.get(); | 761 return iter->second.get(); |
781 } | 762 } |
782 | 763 |
783 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer() {} | 764 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer() {} |
784 | 765 |
785 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() { | 766 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() { |
786 Stop(); | 767 Stop(); |
787 } | 768 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 820 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
840 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 821 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
841 ++periodic_dumps_count_; | 822 ++periodic_dumps_count_; |
842 | 823 |
843 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 824 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
844 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | 825 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
845 } | 826 } |
846 | 827 |
847 } // namespace trace_event | 828 } // namespace trace_event |
848 } // namespace base | 829 } // namespace base |
OLD | NEW |