| Index: base/trace_event/memory_dump_manager.cc
|
| diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
|
| index a5ed760a884070a88a712fb37c2ab59959b26e3b..156f3247b205430f5a5faf5b0091bfb3dd4def87 100644
|
| --- a/base/trace_event/memory_dump_manager.cc
|
| +++ b/base/trace_event/memory_dump_manager.cc
|
| @@ -339,9 +339,12 @@ void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args,
|
| scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state;
|
| {
|
| AutoLock lock(lock_);
|
| - pmd_async_state.reset(
|
| - new ProcessMemoryDumpAsyncState(args, dump_providers_, session_state_,
|
| - callback, dump_thread_->task_runner()));
|
| + // |dump_thread_| can be nullptr is tracing was disabled before reaching
|
| + // here. ContinueAsyncProcessDump is robust enough to tolerate it and will
|
| + // NACK the dump.
|
| + pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
|
| + args, dump_providers_, session_state_, callback,
|
| + dump_thread_ ? dump_thread_->task_runner() : nullptr));
|
| }
|
|
|
| TRACE_EVENT_WITH_FLOW0(kTraceCategory, "MemoryDumpManager::CreateProcessDump",
|
| @@ -404,7 +407,12 @@ void MemoryDumpManager::ContinueAsyncProcessDump(
|
| task_runner = pmd_async_state->dump_thread_task_runner.get();
|
|
|
| bool post_task_failed = false;
|
| - if (!task_runner->BelongsToCurrentThread()) {
|
| + if (!task_runner) {
|
| + // If tracing was disabled before reaching CreateProcessDump() |task_runner|
|
| + // will be null, as the dump_thread_ would have been already torn down.
|
| + post_task_failed = true;
|
| + pmd_async_state->dump_successful = false;
|
| + } else if (!task_runner->BelongsToCurrentThread()) {
|
| // It's time to hop onto another thread.
|
| post_task_failed = !task_runner->PostTask(
|
| FROM_HERE, Bind(&MemoryDumpManager::ContinueAsyncProcessDump,
|
| @@ -441,7 +449,7 @@ void MemoryDumpManager::ContinueAsyncProcessDump(
|
| }
|
| }
|
| should_dump = !mdpinfo->disabled && !post_task_failed;
|
| - }
|
| + } // AutoLock lock(lock_);
|
|
|
| if (disabled_reason) {
|
| LOG(ERROR) << "Disabling MemoryDumpProvider \"" << mdpinfo->name << "\". "
|
| @@ -510,8 +518,13 @@ void MemoryDumpManager::FinalizeDumpAndAddToTrace(
|
| TRACE_EVENT_FLAG_HAS_ID);
|
| }
|
|
|
| + bool tracing_still_enabled;
|
| + TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled);
|
| + if (!tracing_still_enabled)
|
| + pmd_async_state->dump_successful = false;
|
| +
|
| if (!pmd_async_state->callback.is_null()) {
|
| - pmd_async_state->callback.Run(dump_guid, true /* success */);
|
| + pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful);
|
| pmd_async_state->callback.Reset();
|
| }
|
|
|
| @@ -605,6 +618,9 @@ void MemoryDumpManager::OnTraceLogEnabled() {
|
| }
|
|
|
| void MemoryDumpManager::OnTraceLogDisabled() {
|
| + // There might be a memory dump in progress while this happens. Therefore,
|
| + // ensure that the MDM state which depends on the tracing enabled / disabled
|
| + // state is always accessed by the dumping methods holding the |lock_|.
|
| subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
|
| scoped_ptr<Thread> dump_thread;
|
| {
|
| @@ -659,6 +675,7 @@ MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
|
| : req_args(req_args),
|
| session_state(session_state),
|
| callback(callback),
|
| + dump_successful(true),
|
| callback_task_runner(MessageLoop::current()->task_runner()),
|
| dump_thread_task_runner(dump_thread_task_runner) {
|
| pending_dump_providers.reserve(dump_providers.size());
|
|
|