| 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 20 matching lines...) Expand all Loading... |
| 31 | 31 |
| 32 #if defined(OS_WIN) | 32 #if defined(OS_WIN) |
| 33 #include "base/trace_event/winheap_dump_provider_win.h" | 33 #include "base/trace_event/winheap_dump_provider_win.h" |
| 34 #endif | 34 #endif |
| 35 | 35 |
| 36 namespace base { | 36 namespace base { |
| 37 namespace trace_event { | 37 namespace trace_event { |
| 38 | 38 |
| 39 namespace { | 39 namespace { |
| 40 | 40 |
| 41 // Throttle mmaps at a rate of once every kHeavyMmapsDumpsRate standard dumps. | |
| 42 const int kHeavyDumpsRate = 8; // 250 ms * 8 = 2000 ms. | |
| 43 const int kDumpIntervalMs = 250; | |
| 44 const int kTraceEventNumArgs = 1; | 41 const int kTraceEventNumArgs = 1; |
| 45 const char* kTraceEventArgNames[] = {"dumps"}; | 42 const char* kTraceEventArgNames[] = {"dumps"}; |
| 46 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | 43 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; |
| 47 | 44 |
| 48 StaticAtomicSequenceNumber g_next_guid; | 45 StaticAtomicSequenceNumber g_next_guid; |
| 49 uint32 g_periodic_dumps_count = 0; | 46 uint32 g_periodic_dumps_count = 0; |
| 47 uint32 g_heavy_dumps_rate = 0; |
| 50 MemoryDumpManager* g_instance_for_testing = nullptr; | 48 MemoryDumpManager* g_instance_for_testing = nullptr; |
| 51 | 49 |
| 52 void RequestPeriodicGlobalDump() { | 50 void RequestPeriodicGlobalDump() { |
| 53 MemoryDumpArgs::LevelOfDetail dump_level_of_detail = | 51 MemoryDumpArgs::LevelOfDetail dump_level_of_detail; |
| 54 g_periodic_dumps_count == 0 ? MemoryDumpArgs::LevelOfDetail::HIGH | 52 if (g_heavy_dumps_rate == 0) { |
| 55 : MemoryDumpArgs::LevelOfDetail::LOW; | 53 dump_level_of_detail = MemoryDumpArgs::LevelOfDetail::LOW; |
| 56 if (++g_periodic_dumps_count == kHeavyDumpsRate) | 54 } else { |
| 57 g_periodic_dumps_count = 0; | 55 dump_level_of_detail = g_periodic_dumps_count == 0 |
| 56 ? MemoryDumpArgs::LevelOfDetail::HIGH |
| 57 : MemoryDumpArgs::LevelOfDetail::LOW; |
| 58 |
| 59 if (++g_periodic_dumps_count == g_heavy_dumps_rate) |
| 60 g_periodic_dumps_count = 0; |
| 61 } |
| 58 | 62 |
| 59 MemoryDumpArgs dump_args = {dump_level_of_detail}; | 63 MemoryDumpArgs dump_args = {dump_level_of_detail}; |
| 60 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 64 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
| 61 MemoryDumpType::PERIODIC_INTERVAL, dump_args); | 65 MemoryDumpType::PERIODIC_INTERVAL, dump_args); |
| 62 } | 66 } |
| 63 | 67 |
| 64 } // namespace | 68 } // namespace |
| 65 | 69 |
| 66 // static | 70 // static |
| 67 const char* const MemoryDumpManager::kTraceCategory = | 71 const char* const MemoryDumpManager::kTraceCategory = |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 | 113 |
| 110 if (skip_core_dumpers_auto_registration_for_testing_) | 114 if (skip_core_dumpers_auto_registration_for_testing_) |
| 111 return; | 115 return; |
| 112 | 116 |
| 113 // Enable the core dump providers. | 117 // Enable the core dump providers. |
| 114 #if !defined(OS_NACL) | 118 #if !defined(OS_NACL) |
| 115 RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance()); | 119 RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance()); |
| 116 #endif | 120 #endif |
| 117 | 121 |
| 118 #if (defined(OS_LINUX) && !defined(FNL_MUSL)) || defined(OS_ANDROID) | 122 #if (defined(OS_LINUX) && !defined(FNL_MUSL)) || defined(OS_ANDROID) |
| 119 // The memory maps dump provider is currently disabled for security reasons | 123 RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance()); |
| 120 // and will be enabled once tracing is more secure (crbug.com/517906). | |
| 121 // It is still enabled for running benchmarks. | |
| 122 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 123 "enable-memory-benchmarking")) { | |
| 124 RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance()); | |
| 125 } | |
| 126 | |
| 127 RegisterDumpProvider(MallocDumpProvider::GetInstance()); | 124 RegisterDumpProvider(MallocDumpProvider::GetInstance()); |
| 128 system_allocator_pool_name_ = MallocDumpProvider::kAllocatedObjects; | 125 system_allocator_pool_name_ = MallocDumpProvider::kAllocatedObjects; |
| 129 #endif | 126 #endif |
| 130 | 127 |
| 131 #if defined(OS_ANDROID) | 128 #if defined(OS_ANDROID) |
| 132 RegisterDumpProvider(JavaHeapDumpProvider::GetInstance()); | 129 RegisterDumpProvider(JavaHeapDumpProvider::GetInstance()); |
| 133 #endif | 130 #endif |
| 134 | 131 |
| 135 #if defined(OS_WIN) | 132 #if defined(OS_WIN) |
| 136 RegisterDumpProvider(WinHeapDumpProvider::GetInstance()); | 133 RegisterDumpProvider(WinHeapDumpProvider::GetInstance()); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 | 409 |
| 413 session_state_ = new MemoryDumpSessionState(); | 410 session_state_ = new MemoryDumpSessionState(); |
| 414 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) { | 411 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) { |
| 415 it->disabled = false; | 412 it->disabled = false; |
| 416 it->consecutive_failures = 0; | 413 it->consecutive_failures = 0; |
| 417 } | 414 } |
| 418 | 415 |
| 419 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); | 416 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
| 420 | 417 |
| 421 // TODO(primiano): This is a temporary hack to disable periodic memory dumps | 418 // TODO(primiano): This is a temporary hack to disable periodic memory dumps |
| 422 // when running memory benchmarks until they can be enabled/disabled in | 419 // when running memory benchmarks until telemetry uses TraceConfig to |
| 423 // base::trace_event::TraceConfig. See https://goo.gl/5Hj3o0. | 420 // enable/disable periodic dumps. |
| 424 // The same mechanism should be used to disable periodic dumps in tests. | 421 // The same mechanism should be used to disable periodic dumps in tests. |
| 425 if (delegate_->IsCoordinatorProcess() && | 422 if (!delegate_->IsCoordinatorProcess() || |
| 426 !CommandLine::ForCurrentProcess()->HasSwitch( | 423 CommandLine::ForCurrentProcess()->HasSwitch( |
| 427 "enable-memory-benchmarking") && | 424 "enable-memory-benchmarking") || |
| 428 !disable_periodic_dumps_for_testing_) { | 425 disable_periodic_dumps_for_testing_) { |
| 429 g_periodic_dumps_count = 0; | 426 return; |
| 430 periodic_dump_timer_.Start(FROM_HERE, | |
| 431 TimeDelta::FromMilliseconds(kDumpIntervalMs), | |
| 432 base::Bind(&RequestPeriodicGlobalDump)); | |
| 433 } | 427 } |
| 428 |
| 429 // Enable periodic dumps. At the moment the periodic support is limited to at |
| 430 // most one low-detail periodic dump and at most one high-detail periodic |
| 431 // dump. If both are specified the high-detail period must be an integer |
| 432 // multiple of the low-level one. |
| 433 g_periodic_dumps_count = 0; |
| 434 const TraceConfig trace_config = |
| 435 TraceLog::GetInstance()->GetCurrentTraceConfig(); |
| 436 const TraceConfig::MemoryDumpConfig& config_list = |
| 437 trace_config.memory_dump_config(); |
| 438 if (config_list.empty()) |
| 439 return; |
| 440 |
| 441 uint32 min_timer_period_ms = std::numeric_limits<uint32>::max(); |
| 442 uint32 heavy_dump_period_ms = 0; |
| 443 DCHECK_LE(config_list.size(), 2u); |
| 444 for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) { |
| 445 DCHECK(config.periodic_interval_ms); |
| 446 if (config.level_of_detail == MemoryDumpArgs::LevelOfDetail::HIGH) |
| 447 heavy_dump_period_ms = config.periodic_interval_ms; |
| 448 min_timer_period_ms = |
| 449 std::min(min_timer_period_ms, config.periodic_interval_ms); |
| 450 } |
| 451 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms); |
| 452 g_heavy_dumps_rate = heavy_dump_period_ms / min_timer_period_ms; |
| 453 |
| 454 periodic_dump_timer_.Start(FROM_HERE, |
| 455 TimeDelta::FromMilliseconds(min_timer_period_ms), |
| 456 base::Bind(&RequestPeriodicGlobalDump)); |
| 434 } | 457 } |
| 435 | 458 |
| 436 void MemoryDumpManager::OnTraceLogDisabled() { | 459 void MemoryDumpManager::OnTraceLogDisabled() { |
| 437 AutoLock lock(lock_); | 460 AutoLock lock(lock_); |
| 438 periodic_dump_timer_.Stop(); | 461 periodic_dump_timer_.Stop(); |
| 439 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); | 462 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); |
| 440 session_state_ = nullptr; | 463 session_state_ = nullptr; |
| 441 } | 464 } |
| 442 | 465 |
| 443 uint64 MemoryDumpManager::GetTracingProcessId() const { | 466 uint64 MemoryDumpManager::GetTracingProcessId() const { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 472 req_args(req_args), | 495 req_args(req_args), |
| 473 next_dump_provider(next_dump_provider), | 496 next_dump_provider(next_dump_provider), |
| 474 callback(callback), | 497 callback(callback), |
| 475 task_runner(MessageLoop::current()->task_runner()) {} | 498 task_runner(MessageLoop::current()->task_runner()) {} |
| 476 | 499 |
| 477 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { | 500 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { |
| 478 } | 501 } |
| 479 | 502 |
| 480 } // namespace trace_event | 503 } // namespace trace_event |
| 481 } // namespace base | 504 } // namespace base |
| OLD | NEW |