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/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 void InitializeThreadLocalEventBufferIfSupported() { | 146 void InitializeThreadLocalEventBufferIfSupported() { |
147 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); | 147 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); |
148 } | 148 } |
149 | 149 |
150 } // namespace | 150 } // namespace |
151 | 151 |
152 // static | 152 // static |
153 const char* const MemoryDumpManager::kTraceCategoryForTesting = kTraceCategory; | 153 const char* const MemoryDumpManager::kTraceCategoryForTesting = kTraceCategory; |
154 | 154 |
155 // static | 155 // static |
| 156 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; |
| 157 |
| 158 // static |
156 MemoryDumpManager* MemoryDumpManager::GetInstance() { | 159 MemoryDumpManager* MemoryDumpManager::GetInstance() { |
157 if (g_instance_for_testing) | 160 if (g_instance_for_testing) |
158 return g_instance_for_testing; | 161 return g_instance_for_testing; |
159 | 162 |
160 return Singleton<MemoryDumpManager, | 163 return Singleton<MemoryDumpManager, |
161 LeakySingletonTraits<MemoryDumpManager>>::get(); | 164 LeakySingletonTraits<MemoryDumpManager>>::get(); |
162 } | 165 } |
163 | 166 |
164 // static | 167 // static |
165 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { | 168 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 if (did_any_provider_dump && !did_post_any_async_task) | 345 if (did_any_provider_dump && !did_post_any_async_task) |
343 FinalizeDumpAndAddToTrace(pmd_holder); | 346 FinalizeDumpAndAddToTrace(pmd_holder); |
344 } | 347 } |
345 | 348 |
346 // Invokes the MemoryDumpProvider.OnMemoryDump(), taking care of the fail-safe | 349 // Invokes the MemoryDumpProvider.OnMemoryDump(), taking care of the fail-safe |
347 // logic which disables the dumper when failing (crbug.com/461788). | 350 // logic which disables the dumper when failing (crbug.com/461788). |
348 bool MemoryDumpManager::InvokeDumpProviderLocked(MemoryDumpProvider* mdp, | 351 bool MemoryDumpManager::InvokeDumpProviderLocked(MemoryDumpProvider* mdp, |
349 ProcessMemoryDump* pmd) { | 352 ProcessMemoryDump* pmd) { |
350 lock_.AssertAcquired(); | 353 lock_.AssertAcquired(); |
351 bool dump_successful = mdp->OnMemoryDump(pmd); | 354 bool dump_successful = mdp->OnMemoryDump(pmd); |
352 if (!dump_successful) { | 355 MemoryDumpProviderInfo* mdp_info = &dump_providers_.find(mdp)->second; |
353 LOG(ERROR) << "The memory dumper failed, possibly due to sandboxing " | 356 if (dump_successful) { |
354 "(crbug.com/461788), disabling it for current process. Try " | 357 mdp_info->consecutive_failures = 0; |
355 "restarting chrome with the --no-sandbox switch."; | 358 } else { |
356 dump_providers_.find(mdp)->second.disabled = true; | 359 // Disable the MDP if it fails kMaxConsecutiveFailuresCount times |
| 360 // consecutively. |
| 361 mdp_info->consecutive_failures++; |
| 362 if (mdp_info->consecutive_failures >= kMaxConsecutiveFailuresCount) { |
| 363 mdp_info->disabled = true; |
| 364 LOG(ERROR) << "The memory dumper failed, possibly due to sandboxing " |
| 365 "(crbug.com/461788), disabling it for current process. Try " |
| 366 "restarting chrome with the --no-sandbox switch."; |
| 367 } |
357 } | 368 } |
358 return dump_successful; | 369 return dump_successful; |
359 } | 370 } |
360 | 371 |
361 // This is posted to arbitrary threads as a continuation of CreateProcessDump(), | 372 // This is posted to arbitrary threads as a continuation of CreateProcessDump(), |
362 // when one or more MemoryDumpProvider(s) require the OnMemoryDump() call to | 373 // when one or more MemoryDumpProvider(s) require the OnMemoryDump() call to |
363 // happen on a different thread. | 374 // happen on a different thread. |
364 void MemoryDumpManager::ContinueAsyncProcessDump( | 375 void MemoryDumpManager::ContinueAsyncProcessDump( |
365 MemoryDumpProvider* mdp, | 376 MemoryDumpProvider* mdp, |
366 scoped_refptr<ProcessMemoryDumpHolder> pmd_holder) { | 377 scoped_refptr<ProcessMemoryDumpHolder> pmd_holder) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 // Disable all the providers. | 413 // Disable all the providers. |
403 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) | 414 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) |
404 it->second.disabled = true; | 415 it->second.disabled = true; |
405 return; | 416 return; |
406 } | 417 } |
407 | 418 |
408 session_state_ = new MemoryDumpSessionState(); | 419 session_state_ = new MemoryDumpSessionState(); |
409 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) { | 420 for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) { |
410 MemoryDumpProviderInfo& mdp_info = it->second; | 421 MemoryDumpProviderInfo& mdp_info = it->second; |
411 mdp_info.disabled = false; | 422 mdp_info.disabled = false; |
| 423 mdp_info.consecutive_failures = 0; |
412 if (mdp_info.task_runner) { | 424 if (mdp_info.task_runner) { |
413 // The thread local event buffer must be initialized at this point as it | 425 // The thread local event buffer must be initialized at this point as it |
414 // registers its own dump provider (for tracing overhead acounting). | 426 // registers its own dump provider (for tracing overhead acounting). |
415 // The registration cannot happen lazily during the first TRACE_EVENT* | 427 // The registration cannot happen lazily during the first TRACE_EVENT* |
416 // as it might end up registering the ThreadLocalEventBuffer while | 428 // as it might end up registering the ThreadLocalEventBuffer while |
417 // in onMemoryDump(), which will deadlock. | 429 // in onMemoryDump(), which will deadlock. |
418 mdp_info.task_runner->PostTask( | 430 mdp_info.task_runner->PostTask( |
419 FROM_HERE, Bind(&InitializeThreadLocalEventBufferIfSupported)); | 431 FROM_HERE, Bind(&InitializeThreadLocalEventBufferIfSupported)); |
420 } | 432 } |
421 } | 433 } |
(...skipping 10 matching lines...) Expand all Loading... |
432 | 444 |
433 void MemoryDumpManager::OnTraceLogDisabled() { | 445 void MemoryDumpManager::OnTraceLogDisabled() { |
434 AutoLock lock(lock_); | 446 AutoLock lock(lock_); |
435 periodic_dump_timer_.Stop(); | 447 periodic_dump_timer_.Stop(); |
436 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); | 448 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); |
437 session_state_ = nullptr; | 449 session_state_ = nullptr; |
438 } | 450 } |
439 | 451 |
440 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo( | 452 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo( |
441 const scoped_refptr<SingleThreadTaskRunner>& task_runner) | 453 const scoped_refptr<SingleThreadTaskRunner>& task_runner) |
442 : task_runner(task_runner), disabled(false) { | 454 : task_runner(task_runner), consecutive_failures(0), disabled(false) { |
443 } | 455 } |
444 MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() { | 456 MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() { |
445 } | 457 } |
446 | 458 |
447 } // namespace trace_event | 459 } // namespace trace_event |
448 } // namespace base | 460 } // namespace base |
OLD | NEW |