| 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 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
| 11 #include "base/base_switches.h" | 11 #include "base/base_switches.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
| 16 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 17 #include "base/trace_event/heap_profiler.h" |
| 17 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 18 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
| 18 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" | 19 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" |
| 19 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" | 20 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" |
| 20 #include "base/trace_event/malloc_dump_provider.h" | 21 #include "base/trace_event/malloc_dump_provider.h" |
| 21 #include "base/trace_event/memory_dump_provider.h" | 22 #include "base/trace_event/memory_dump_provider.h" |
| 22 #include "base/trace_event/memory_dump_session_state.h" | 23 #include "base/trace_event/memory_dump_session_state.h" |
| 23 #include "base/trace_event/process_memory_dump.h" | 24 #include "base/trace_event/process_memory_dump.h" |
| 24 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
| 25 #include "base/trace_event/trace_event_argument.h" | 26 #include "base/trace_event/trace_event_argument.h" |
| 26 #include "build/build_config.h" | 27 #include "build/build_config.h" |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 // PostTask is always required for a generic SequencedTaskRunner to ensure that | 396 // PostTask is always required for a generic SequencedTaskRunner to ensure that |
| 396 // no other task is running on it concurrently. SetupNextMemoryDump() and | 397 // no other task is running on it concurrently. SetupNextMemoryDump() and |
| 397 // InvokeOnMemoryDump() are called alternatively which linearizes the dump | 398 // InvokeOnMemoryDump() are called alternatively which linearizes the dump |
| 398 // provider's OnMemoryDump invocations. | 399 // provider's OnMemoryDump invocations. |
| 399 // At most one of either SetupNextMemoryDump() or InvokeOnMemoryDump() can be | 400 // At most one of either SetupNextMemoryDump() or InvokeOnMemoryDump() can be |
| 400 // active at any time for a given PMD, regardless of status of the |lock_|. | 401 // active at any time for a given PMD, regardless of status of the |lock_|. |
| 401 // |lock_| is used in these functions purely to ensure consistency w.r.t. | 402 // |lock_| is used in these functions purely to ensure consistency w.r.t. |
| 402 // (un)registrations of |dump_providers_|. | 403 // (un)registrations of |dump_providers_|. |
| 403 void MemoryDumpManager::SetupNextMemoryDump( | 404 void MemoryDumpManager::SetupNextMemoryDump( |
| 404 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) { | 405 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) { |
| 406 HEAP_PROFILER_SCOPED_IGNORE; |
| 405 // Initalizes the ThreadLocalEventBuffer to guarantee that the TRACE_EVENTs | 407 // Initalizes the ThreadLocalEventBuffer to guarantee that the TRACE_EVENTs |
| 406 // in the PostTask below don't end up registering their own dump providers | 408 // in the PostTask below don't end up registering their own dump providers |
| 407 // (for discounting trace memory overhead) while holding the |lock_|. | 409 // (for discounting trace memory overhead) while holding the |lock_|. |
| 408 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); | 410 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); |
| 409 | 411 |
| 410 // |dump_thread_| might be destroyed before getting this point. | 412 // |dump_thread_| might be destroyed before getting this point. |
| 411 // It means that tracing was disabled right before starting this dump. | 413 // It means that tracing was disabled right before starting this dump. |
| 412 // Anyway either tracing is stopped or this was the last hop, create a trace | 414 // Anyway either tracing is stopped or this was the last hop, create a trace |
| 413 // event, add it to the trace and finalize process dump invoking the callback. | 415 // event, add it to the trace and finalize process dump invoking the callback. |
| 414 if (!pmd_async_state->dump_thread_task_runner.get()) { | 416 if (!pmd_async_state->dump_thread_task_runner.get()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 pmd_async_state->pending_dump_providers.pop_back(); | 469 pmd_async_state->pending_dump_providers.pop_back(); |
| 468 SetupNextMemoryDump(std::move(pmd_async_state)); | 470 SetupNextMemoryDump(std::move(pmd_async_state)); |
| 469 } | 471 } |
| 470 | 472 |
| 471 // This function is called on the right task runner for current MDP. It is | 473 // This function is called on the right task runner for current MDP. It is |
| 472 // either the task runner specified by MDP or |dump_thread_task_runner| if the | 474 // either the task runner specified by MDP or |dump_thread_task_runner| if the |
| 473 // MDP did not specify task runner. Invokes the dump provider's OnMemoryDump() | 475 // MDP did not specify task runner. Invokes the dump provider's OnMemoryDump() |
| 474 // (unless disabled). | 476 // (unless disabled). |
| 475 void MemoryDumpManager::InvokeOnMemoryDump( | 477 void MemoryDumpManager::InvokeOnMemoryDump( |
| 476 ProcessMemoryDumpAsyncState* owned_pmd_async_state) { | 478 ProcessMemoryDumpAsyncState* owned_pmd_async_state) { |
| 479 HEAP_PROFILER_SCOPED_IGNORE; |
| 477 // In theory |owned_pmd_async_state| should be a scoped_ptr. The only reason | 480 // In theory |owned_pmd_async_state| should be a scoped_ptr. The only reason |
| 478 // why it isn't is because of the corner case logic of |did_post_task| | 481 // why it isn't is because of the corner case logic of |did_post_task| |
| 479 // above, which needs to take back the ownership of the |pmd_async_state| when | 482 // above, which needs to take back the ownership of the |pmd_async_state| when |
| 480 // the PostTask() fails. | 483 // the PostTask() fails. |
| 481 // Unfortunately, PostTask() destroys the scoped_ptr arguments upon failure | 484 // Unfortunately, PostTask() destroys the scoped_ptr arguments upon failure |
| 482 // to prevent accidental leaks. Using a scoped_ptr would prevent us to to | 485 // to prevent accidental leaks. Using a scoped_ptr would prevent us to to |
| 483 // skip the hop and move on. Hence the manual naked -> scoped ptr juggling. | 486 // skip the hop and move on. Hence the manual naked -> scoped ptr juggling. |
| 484 auto pmd_async_state = WrapUnique(owned_pmd_async_state); | 487 auto pmd_async_state = WrapUnique(owned_pmd_async_state); |
| 485 owned_pmd_async_state = nullptr; | 488 owned_pmd_async_state = nullptr; |
| 486 | 489 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 dump_successful ? 0 : mdpinfo->consecutive_failures + 1; | 531 dump_successful ? 0 : mdpinfo->consecutive_failures + 1; |
| 529 } | 532 } |
| 530 | 533 |
| 531 pmd_async_state->pending_dump_providers.pop_back(); | 534 pmd_async_state->pending_dump_providers.pop_back(); |
| 532 SetupNextMemoryDump(std::move(pmd_async_state)); | 535 SetupNextMemoryDump(std::move(pmd_async_state)); |
| 533 } | 536 } |
| 534 | 537 |
| 535 // static | 538 // static |
| 536 void MemoryDumpManager::FinalizeDumpAndAddToTrace( | 539 void MemoryDumpManager::FinalizeDumpAndAddToTrace( |
| 537 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) { | 540 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) { |
| 541 HEAP_PROFILER_SCOPED_IGNORE; |
| 538 DCHECK(pmd_async_state->pending_dump_providers.empty()); | 542 DCHECK(pmd_async_state->pending_dump_providers.empty()); |
| 539 const uint64_t dump_guid = pmd_async_state->req_args.dump_guid; | 543 const uint64_t dump_guid = pmd_async_state->req_args.dump_guid; |
| 540 if (!pmd_async_state->callback_task_runner->BelongsToCurrentThread()) { | 544 if (!pmd_async_state->callback_task_runner->BelongsToCurrentThread()) { |
| 541 scoped_refptr<SingleThreadTaskRunner> callback_task_runner = | 545 scoped_refptr<SingleThreadTaskRunner> callback_task_runner = |
| 542 pmd_async_state->callback_task_runner; | 546 pmd_async_state->callback_task_runner; |
| 543 callback_task_runner->PostTask( | 547 callback_task_runner->PostTask( |
| 544 FROM_HERE, Bind(&MemoryDumpManager::FinalizeDumpAndAddToTrace, | 548 FROM_HERE, Bind(&MemoryDumpManager::FinalizeDumpAndAddToTrace, |
| 545 Passed(&pmd_async_state))); | 549 Passed(&pmd_async_state))); |
| 546 return; | 550 return; |
| 547 } | 551 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 if (iter == process_dumps.end()) { | 755 if (iter == process_dumps.end()) { |
| 752 std::unique_ptr<ProcessMemoryDump> new_pmd( | 756 std::unique_ptr<ProcessMemoryDump> new_pmd( |
| 753 new ProcessMemoryDump(session_state)); | 757 new ProcessMemoryDump(session_state)); |
| 754 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; | 758 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; |
| 755 } | 759 } |
| 756 return iter->second.get(); | 760 return iter->second.get(); |
| 757 } | 761 } |
| 758 | 762 |
| 759 } // namespace trace_event | 763 } // namespace trace_event |
| 760 } // namespace base | 764 } // namespace base |
| OLD | NEW |