| Index: trace_event/memory_dump_manager.cc
|
| diff --git a/trace_event/memory_dump_manager.cc b/trace_event/memory_dump_manager.cc
|
| index 71a9daee3ff60b5e4a10c0524a1c9af78122301b..1c10d1c097b5e16e9c9c3feabc932b8538da5613 100644
|
| --- a/trace_event/memory_dump_manager.cc
|
| +++ b/trace_event/memory_dump_manager.cc
|
| @@ -48,21 +48,20 @@ uint32 g_heavy_dumps_rate = 0;
|
| MemoryDumpManager* g_instance_for_testing = nullptr;
|
|
|
| void RequestPeriodicGlobalDump() {
|
| - MemoryDumpArgs::LevelOfDetail dump_level_of_detail;
|
| + MemoryDumpLevelOfDetail level_of_detail;
|
| if (g_heavy_dumps_rate == 0) {
|
| - dump_level_of_detail = MemoryDumpArgs::LevelOfDetail::LOW;
|
| + level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
|
| } else {
|
| - dump_level_of_detail = g_periodic_dumps_count == 0
|
| - ? MemoryDumpArgs::LevelOfDetail::HIGH
|
| - : MemoryDumpArgs::LevelOfDetail::LOW;
|
| + level_of_detail = g_periodic_dumps_count == 0
|
| + ? MemoryDumpLevelOfDetail::DETAILED
|
| + : MemoryDumpLevelOfDetail::LIGHT;
|
|
|
| if (++g_periodic_dumps_count == g_heavy_dumps_rate)
|
| g_periodic_dumps_count = 0;
|
| }
|
|
|
| - MemoryDumpArgs dump_args = {dump_level_of_detail};
|
| MemoryDumpManager::GetInstance()->RequestGlobalDump(
|
| - MemoryDumpType::PERIODIC_INTERVAL, dump_args);
|
| + MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
|
| }
|
|
|
| } // namespace
|
| @@ -78,6 +77,16 @@ const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3;
|
| const uint64 MemoryDumpManager::kInvalidTracingProcessId = 0;
|
|
|
| // static
|
| +const char* const MemoryDumpManager::kSystemAllocatorPoolName =
|
| +#if defined(OS_LINUX) || defined(OS_ANDROID)
|
| + MallocDumpProvider::kAllocatedObjects;
|
| +#elif defined(OS_WIN)
|
| + WinHeapDumpProvider::kAllocatedObjects;
|
| +#else
|
| + nullptr;
|
| +#endif
|
| +
|
| +// static
|
| MemoryDumpManager* MemoryDumpManager::GetInstance() {
|
| if (g_instance_for_testing)
|
| return g_instance_for_testing;
|
| @@ -95,50 +104,54 @@ void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) {
|
|
|
| MemoryDumpManager::MemoryDumpManager()
|
| : delegate_(nullptr),
|
| + is_coordinator_(false),
|
| memory_tracing_enabled_(0),
|
| tracing_process_id_(kInvalidTracingProcessId),
|
| - system_allocator_pool_name_(nullptr),
|
| - skip_core_dumpers_auto_registration_for_testing_(false),
|
| - disable_periodic_dumps_for_testing_(false) {
|
| + skip_core_dumpers_auto_registration_for_testing_(false) {
|
| g_next_guid.GetNext(); // Make sure that first guid is not zero.
|
| }
|
|
|
| MemoryDumpManager::~MemoryDumpManager() {
|
| - base::trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
|
| + TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
|
| }
|
|
|
| -void MemoryDumpManager::Initialize() {
|
| - TRACE_EVENT0(kTraceCategory, "init"); // Add to trace-viewer category list.
|
| - trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
|
| -
|
| - if (skip_core_dumpers_auto_registration_for_testing_)
|
| - return;
|
| +void MemoryDumpManager::Initialize(MemoryDumpManagerDelegate* delegate,
|
| + bool is_coordinator) {
|
| + {
|
| + AutoLock lock(lock_);
|
| + DCHECK(delegate);
|
| + DCHECK(!delegate_);
|
| + delegate_ = delegate;
|
| + is_coordinator_ = is_coordinator;
|
| + }
|
|
|
| // Enable the core dump providers.
|
| + if (!skip_core_dumpers_auto_registration_for_testing_) {
|
| #if !defined(OS_NACL)
|
| - RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance());
|
| + RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance());
|
| #endif
|
|
|
| #if (defined(OS_LINUX) && !defined(FNL_MUSL)) || defined(OS_ANDROID)
|
| - RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance());
|
| - RegisterDumpProvider(MallocDumpProvider::GetInstance());
|
| - system_allocator_pool_name_ = MallocDumpProvider::kAllocatedObjects;
|
| + RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance());
|
| + RegisterDumpProvider(MallocDumpProvider::GetInstance());
|
| #endif
|
|
|
| #if defined(OS_ANDROID)
|
| - RegisterDumpProvider(JavaHeapDumpProvider::GetInstance());
|
| + RegisterDumpProvider(JavaHeapDumpProvider::GetInstance());
|
| #endif
|
|
|
| #if defined(OS_WIN)
|
| - RegisterDumpProvider(WinHeapDumpProvider::GetInstance());
|
| - system_allocator_pool_name_ = WinHeapDumpProvider::kAllocatedObjects;
|
| + RegisterDumpProvider(WinHeapDumpProvider::GetInstance());
|
| #endif
|
| -}
|
| + } // !skip_core_dumpers_auto_registration_for_testing_
|
|
|
| -void MemoryDumpManager::SetDelegate(MemoryDumpManagerDelegate* delegate) {
|
| - AutoLock lock(lock_);
|
| - DCHECK_EQ(static_cast<MemoryDumpManagerDelegate*>(nullptr), delegate_);
|
| - delegate_ = delegate;
|
| + // If tracing was enabled before initializing MemoryDumpManager, we missed the
|
| + // OnTraceLogEnabled() event. Synthetize it so we can late-join the party.
|
| + bool is_tracing_already_enabled = TraceLog::GetInstance()->IsEnabled();
|
| + TRACE_EVENT0(kTraceCategory, "init"); // Add to trace-viewer category list.
|
| + TraceLog::GetInstance()->AddEnabledStateObserver(this);
|
| + if (is_tracing_already_enabled)
|
| + OnTraceLogEnabled();
|
| }
|
|
|
| void MemoryDumpManager::RegisterDumpProvider(
|
| @@ -189,9 +202,10 @@ void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) {
|
| mdp_iter->unregistered = true;
|
| }
|
|
|
| -void MemoryDumpManager::RequestGlobalDump(MemoryDumpType dump_type,
|
| - const MemoryDumpArgs& dump_args,
|
| - const MemoryDumpCallback& callback) {
|
| +void MemoryDumpManager::RequestGlobalDump(
|
| + MemoryDumpType dump_type,
|
| + MemoryDumpLevelOfDetail level_of_detail,
|
| + const MemoryDumpCallback& callback) {
|
| // Bail out immediately if tracing is not enabled at all.
|
| if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) {
|
| if (!callback.is_null())
|
| @@ -202,27 +216,27 @@ void MemoryDumpManager::RequestGlobalDump(MemoryDumpType dump_type,
|
| const uint64 guid =
|
| TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext());
|
|
|
| - // The delegate_ is supposed to be thread safe, immutable and long lived.
|
| - // No need to keep the lock after we ensure that a delegate has been set.
|
| + // Technically there is no need to grab the |lock_| here as the delegate is
|
| + // long-lived and can only be set by Initialize(), which is locked and
|
| + // necessarily happens before memory_tracing_enabled_ == true.
|
| + // Not taking the |lock_|, though, is lakely make TSan barf and, at this point
|
| + // (memory-infra is enabled) we're not in the fast-path anymore.
|
| MemoryDumpManagerDelegate* delegate;
|
| {
|
| AutoLock lock(lock_);
|
| delegate = delegate_;
|
| }
|
|
|
| - if (delegate) {
|
| - // The delegate is in charge to coordinate the request among all the
|
| - // processes and call the CreateLocalDumpPoint on the local process.
|
| - MemoryDumpRequestArgs args = {guid, dump_type, dump_args};
|
| - delegate->RequestGlobalMemoryDump(args, callback);
|
| - } else if (!callback.is_null()) {
|
| - callback.Run(guid, false /* success */);
|
| - }
|
| + // The delegate will coordinate the IPC broadcast and at some point invoke
|
| + // CreateProcessDump() to get a dump for the current process.
|
| + MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail};
|
| + delegate->RequestGlobalMemoryDump(args, callback);
|
| }
|
|
|
| -void MemoryDumpManager::RequestGlobalDump(MemoryDumpType dump_type,
|
| - const MemoryDumpArgs& dump_args) {
|
| - RequestGlobalDump(dump_type, dump_args, MemoryDumpCallback());
|
| +void MemoryDumpManager::RequestGlobalDump(
|
| + MemoryDumpType dump_type,
|
| + MemoryDumpLevelOfDetail level_of_detail) {
|
| + RequestGlobalDump(dump_type, level_of_detail, MemoryDumpCallback());
|
| }
|
|
|
| void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args,
|
| @@ -305,8 +319,9 @@ void MemoryDumpManager::ContinueAsyncProcessDump(
|
| bool dump_successful = false;
|
|
|
| if (!skip_dump) {
|
| - dump_successful = mdp->OnMemoryDump(pmd_async_state->req_args.dump_args,
|
| - &pmd_async_state->process_memory_dump);
|
| + MemoryDumpArgs args = {pmd_async_state->req_args.level_of_detail};
|
| + dump_successful =
|
| + mdp->OnMemoryDump(args, &pmd_async_state->process_memory_dump);
|
| }
|
|
|
| {
|
| @@ -386,11 +401,10 @@ void MemoryDumpManager::AbortDumpLocked(
|
| }
|
|
|
| void MemoryDumpManager::OnTraceLogEnabled() {
|
| - // TODO(primiano): at this point we query TraceLog::GetCurrentCategoryFilter
|
| - // to figure out (and cache) which dumpers should be enabled or not.
|
| - // For the moment piggy back everything on the generic "memory" category.
|
| bool enabled;
|
| TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled);
|
| + if (!enabled)
|
| + return;
|
|
|
| // Initialize the TraceLog for the current thread. This is to avoid that the
|
| // TraceLog memory dump provider is registered lazily in the PostTask() below
|
| @@ -399,13 +413,7 @@ void MemoryDumpManager::OnTraceLogEnabled() {
|
|
|
| AutoLock lock(lock_);
|
|
|
| - // There is no point starting the tracing without a delegate.
|
| - if (!enabled || !delegate_) {
|
| - // Disable all the providers.
|
| - for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it)
|
| - it->disabled = true;
|
| - return;
|
| - }
|
| + DCHECK(delegate_); // At this point we must have a delegate.
|
|
|
| session_state_ = new MemoryDumpSessionState();
|
| for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) {
|
| @@ -417,12 +425,10 @@ void MemoryDumpManager::OnTraceLogEnabled() {
|
|
|
| // TODO(primiano): This is a temporary hack to disable periodic memory dumps
|
| // when running memory benchmarks until telemetry uses TraceConfig to
|
| - // enable/disable periodic dumps.
|
| - // The same mechanism should be used to disable periodic dumps in tests.
|
| - if (!delegate_->IsCoordinatorProcess() ||
|
| + // enable/disable periodic dumps. See crbug.com/529184 .
|
| + if (!is_coordinator_ ||
|
| CommandLine::ForCurrentProcess()->HasSwitch(
|
| - "enable-memory-benchmarking") ||
|
| - disable_periodic_dumps_for_testing_) {
|
| + "enable-memory-benchmarking")) {
|
| return;
|
| }
|
|
|
| @@ -443,7 +449,7 @@ void MemoryDumpManager::OnTraceLogEnabled() {
|
| DCHECK_LE(config_list.size(), 2u);
|
| for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) {
|
| DCHECK(config.periodic_interval_ms);
|
| - if (config.level_of_detail == MemoryDumpArgs::LevelOfDetail::HIGH)
|
| + if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED)
|
| heavy_dump_period_ms = config.periodic_interval_ms;
|
| min_timer_period_ms =
|
| std::min(min_timer_period_ms, config.periodic_interval_ms);
|
|
|