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 | 8 |
9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 const int kTraceEventNumArgs = 1; | 41 const int kTraceEventNumArgs = 1; |
42 const char* kTraceEventArgNames[] = {"dumps"}; | 42 const char* kTraceEventArgNames[] = {"dumps"}; |
43 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | 43 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; |
44 | 44 |
45 StaticAtomicSequenceNumber g_next_guid; | 45 StaticAtomicSequenceNumber g_next_guid; |
46 uint32 g_periodic_dumps_count = 0; | 46 uint32 g_periodic_dumps_count = 0; |
47 uint32 g_heavy_dumps_rate = 0; | 47 uint32 g_heavy_dumps_rate = 0; |
48 MemoryDumpManager* g_instance_for_testing = nullptr; | 48 MemoryDumpManager* g_instance_for_testing = nullptr; |
49 | 49 |
50 void RequestPeriodicGlobalDump() { | 50 void RequestPeriodicGlobalDump() { |
51 MemoryDumpArgs::LevelOfDetail dump_level_of_detail; | 51 MemoryDumpLevelOfDetail level_of_detail; |
52 if (g_heavy_dumps_rate == 0) { | 52 if (g_heavy_dumps_rate == 0) { |
53 dump_level_of_detail = MemoryDumpArgs::LevelOfDetail::LOW; | 53 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; |
54 } else { | 54 } else { |
55 dump_level_of_detail = g_periodic_dumps_count == 0 | 55 level_of_detail = g_periodic_dumps_count == 0 |
56 ? MemoryDumpArgs::LevelOfDetail::HIGH | 56 ? MemoryDumpLevelOfDetail::DETAILED |
57 : MemoryDumpArgs::LevelOfDetail::LOW; | 57 : MemoryDumpLevelOfDetail::LIGHT; |
58 | 58 |
59 if (++g_periodic_dumps_count == g_heavy_dumps_rate) | 59 if (++g_periodic_dumps_count == g_heavy_dumps_rate) |
60 g_periodic_dumps_count = 0; | 60 g_periodic_dumps_count = 0; |
61 } | 61 } |
62 | 62 |
63 MemoryDumpArgs dump_args = {dump_level_of_detail}; | |
64 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 63 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
65 MemoryDumpType::PERIODIC_INTERVAL, dump_args); | 64 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
66 } | 65 } |
67 | 66 |
68 } // namespace | 67 } // namespace |
69 | 68 |
70 // static | 69 // static |
71 const char* const MemoryDumpManager::kTraceCategory = | 70 const char* const MemoryDumpManager::kTraceCategory = |
72 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 71 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
73 | 72 |
74 // static | 73 // static |
75 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; | 74 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // race-free. If you hit this DCHECK, your MDP has a bug. | 196 // race-free. If you hit this DCHECK, your MDP has a bug. |
198 DCHECK_IMPLIES( | 197 DCHECK_IMPLIES( |
199 subtle::NoBarrier_Load(&memory_tracing_enabled_), | 198 subtle::NoBarrier_Load(&memory_tracing_enabled_), |
200 mdp_iter->task_runner && mdp_iter->task_runner->BelongsToCurrentThread()) | 199 mdp_iter->task_runner && mdp_iter->task_runner->BelongsToCurrentThread()) |
201 << "The MemoryDumpProvider attempted to unregister itself in a racy way. " | 200 << "The MemoryDumpProvider attempted to unregister itself in a racy way. " |
202 << "Please file a crbug."; | 201 << "Please file a crbug."; |
203 | 202 |
204 mdp_iter->unregistered = true; | 203 mdp_iter->unregistered = true; |
205 } | 204 } |
206 | 205 |
207 void MemoryDumpManager::RequestGlobalDump(MemoryDumpType dump_type, | 206 void MemoryDumpManager::RequestGlobalDump( |
208 const MemoryDumpArgs& dump_args, | 207 MemoryDumpType dump_type, |
209 const MemoryDumpCallback& callback) { | 208 MemoryDumpLevelOfDetail level_of_detail, |
| 209 const MemoryDumpCallback& callback) { |
210 // Bail out immediately if tracing is not enabled at all. | 210 // Bail out immediately if tracing is not enabled at all. |
211 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) { | 211 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) { |
212 if (!callback.is_null()) | 212 if (!callback.is_null()) |
213 callback.Run(0u /* guid */, false /* success */); | 213 callback.Run(0u /* guid */, false /* success */); |
214 return; | 214 return; |
215 } | 215 } |
216 | 216 |
217 const uint64 guid = | 217 const uint64 guid = |
218 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); | 218 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); |
219 | 219 |
220 // Technically there is no need to grab the |lock_| here as the delegate is | 220 // Technically there is no need to grab the |lock_| here as the delegate is |
221 // long-lived and can only be set by Initialize(), which is locked and | 221 // long-lived and can only be set by Initialize(), which is locked and |
222 // necessarily happens before memory_tracing_enabled_ == true. | 222 // necessarily happens before memory_tracing_enabled_ == true. |
223 // Not taking the |lock_|, though, is lakely make TSan barf and, at this point | 223 // Not taking the |lock_|, though, is lakely make TSan barf and, at this point |
224 // (memory-infra is enabled) we're not in the fast-path anymore. | 224 // (memory-infra is enabled) we're not in the fast-path anymore. |
225 MemoryDumpManagerDelegate* delegate; | 225 MemoryDumpManagerDelegate* delegate; |
226 { | 226 { |
227 AutoLock lock(lock_); | 227 AutoLock lock(lock_); |
228 delegate = delegate_; | 228 delegate = delegate_; |
229 } | 229 } |
230 | 230 |
231 // The delegate will coordinate the IPC broadcast and at some point invoke | 231 // The delegate will coordinate the IPC broadcast and at some point invoke |
232 // CreateProcessDump() to get a dump for the current process. | 232 // CreateProcessDump() to get a dump for the current process. |
233 MemoryDumpRequestArgs args = {guid, dump_type, dump_args}; | 233 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail}; |
234 delegate->RequestGlobalMemoryDump(args, callback); | 234 delegate->RequestGlobalMemoryDump(args, callback); |
235 } | 235 } |
236 | 236 |
237 void MemoryDumpManager::RequestGlobalDump(MemoryDumpType dump_type, | 237 void MemoryDumpManager::RequestGlobalDump( |
238 const MemoryDumpArgs& dump_args) { | 238 MemoryDumpType dump_type, |
239 RequestGlobalDump(dump_type, dump_args, MemoryDumpCallback()); | 239 MemoryDumpLevelOfDetail level_of_detail) { |
| 240 RequestGlobalDump(dump_type, level_of_detail, MemoryDumpCallback()); |
240 } | 241 } |
241 | 242 |
242 void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, | 243 void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, |
243 const MemoryDumpCallback& callback) { | 244 const MemoryDumpCallback& callback) { |
244 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state; | 245 scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state; |
245 { | 246 { |
246 AutoLock lock(lock_); | 247 AutoLock lock(lock_); |
247 pmd_async_state.reset(new ProcessMemoryDumpAsyncState( | 248 pmd_async_state.reset(new ProcessMemoryDumpAsyncState( |
248 args, dump_providers_.begin(), session_state_, callback)); | 249 args, dump_providers_.begin(), session_state_, callback)); |
249 } | 250 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 mdp_info->disabled = true; | 313 mdp_info->disabled = true; |
313 return AbortDumpLocked(callback, callback_task_runner, dump_guid); | 314 return AbortDumpLocked(callback, callback_task_runner, dump_guid); |
314 } | 315 } |
315 } // AutoLock(lock_) | 316 } // AutoLock(lock_) |
316 | 317 |
317 // Invoke the dump provider without holding the |lock_|. | 318 // Invoke the dump provider without holding the |lock_|. |
318 bool finalize = false; | 319 bool finalize = false; |
319 bool dump_successful = false; | 320 bool dump_successful = false; |
320 | 321 |
321 if (!skip_dump) { | 322 if (!skip_dump) { |
322 dump_successful = mdp->OnMemoryDump(pmd_async_state->req_args.dump_args, | 323 MemoryDumpArgs args = {pmd_async_state->req_args.level_of_detail}; |
323 &pmd_async_state->process_memory_dump); | 324 dump_successful = |
| 325 mdp->OnMemoryDump(args, &pmd_async_state->process_memory_dump); |
324 } | 326 } |
325 | 327 |
326 { | 328 { |
327 AutoLock lock(lock_); | 329 AutoLock lock(lock_); |
328 auto mdp_info = pmd_async_state->next_dump_provider; | 330 auto mdp_info = pmd_async_state->next_dump_provider; |
329 if (dump_successful) { | 331 if (dump_successful) { |
330 mdp_info->consecutive_failures = 0; | 332 mdp_info->consecutive_failures = 0; |
331 } else if (!skip_dump) { | 333 } else if (!skip_dump) { |
332 ++mdp_info->consecutive_failures; | 334 ++mdp_info->consecutive_failures; |
333 if (mdp_info->consecutive_failures >= kMaxConsecutiveFailuresCount) { | 335 if (mdp_info->consecutive_failures >= kMaxConsecutiveFailuresCount) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 const TraceConfig::MemoryDumpConfig& config_list = | 443 const TraceConfig::MemoryDumpConfig& config_list = |
442 trace_config.memory_dump_config(); | 444 trace_config.memory_dump_config(); |
443 if (config_list.empty()) | 445 if (config_list.empty()) |
444 return; | 446 return; |
445 | 447 |
446 uint32 min_timer_period_ms = std::numeric_limits<uint32>::max(); | 448 uint32 min_timer_period_ms = std::numeric_limits<uint32>::max(); |
447 uint32 heavy_dump_period_ms = 0; | 449 uint32 heavy_dump_period_ms = 0; |
448 DCHECK_LE(config_list.size(), 2u); | 450 DCHECK_LE(config_list.size(), 2u); |
449 for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) { | 451 for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) { |
450 DCHECK(config.periodic_interval_ms); | 452 DCHECK(config.periodic_interval_ms); |
451 if (config.level_of_detail == MemoryDumpArgs::LevelOfDetail::HIGH) | 453 if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) |
452 heavy_dump_period_ms = config.periodic_interval_ms; | 454 heavy_dump_period_ms = config.periodic_interval_ms; |
453 min_timer_period_ms = | 455 min_timer_period_ms = |
454 std::min(min_timer_period_ms, config.periodic_interval_ms); | 456 std::min(min_timer_period_ms, config.periodic_interval_ms); |
455 } | 457 } |
456 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); | 458 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); |
457 g_heavy_dumps_rate = heavy_dump_period_ms / min_timer_period_ms; | 459 g_heavy_dumps_rate = heavy_dump_period_ms / min_timer_period_ms; |
458 | 460 |
459 periodic_dump_timer_.Start(FROM_HERE, | 461 periodic_dump_timer_.Start(FROM_HERE, |
460 TimeDelta::FromMilliseconds(min_timer_period_ms), | 462 TimeDelta::FromMilliseconds(min_timer_period_ms), |
461 base::Bind(&RequestPeriodicGlobalDump)); | 463 base::Bind(&RequestPeriodicGlobalDump)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 next_dump_provider(next_dump_provider), | 503 next_dump_provider(next_dump_provider), |
502 callback(callback), | 504 callback(callback), |
503 task_runner(MessageLoop::current()->task_runner()) { | 505 task_runner(MessageLoop::current()->task_runner()) { |
504 } | 506 } |
505 | 507 |
506 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { | 508 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { |
507 } | 509 } |
508 | 510 |
509 } // namespace trace_event | 511 } // namespace trace_event |
510 } // namespace base | 512 } // namespace base |
OLD | NEW |