Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: base/trace_event/memory_dump_manager.cc

Issue 2777093009: [Memory UMA] Return a memory summary struct with the ack message (Closed)
Patch Set: Readd the extra_process_dump map Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <inttypes.h> 7 #include <inttypes.h>
8 #include <stdio.h> 8 #include <stdio.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 "cc::SoftwareImageDecodeCache", 75 "cc::SoftwareImageDecodeCache",
76 "cc::StagingBufferPool", 76 "cc::StagingBufferPool",
77 "gpu::BufferManager", 77 "gpu::BufferManager",
78 "gpu::MappedMemoryManager", 78 "gpu::MappedMemoryManager",
79 "gpu::RenderbufferManager", 79 "gpu::RenderbufferManager",
80 "BlacklistTestDumpProvider" // for testing 80 "BlacklistTestDumpProvider" // for testing
81 }; 81 };
82 82
83 // Callback wrapper to hook upon the completion of RequestGlobalDump() and 83 // Callback wrapper to hook upon the completion of RequestGlobalDump() and
84 // inject trace markers. 84 // inject trace markers.
85 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback, 85 void OnGlobalDumpDone(GlobalMemoryDumpCallback wrapped_callback,
86 uint64_t dump_guid, 86 uint64_t dump_guid,
87 bool success) { 87 bool success) {
88 char guid_str[20]; 88 char guid_str[20];
89 sprintf(guid_str, "0x%" PRIx64, dump_guid); 89 sprintf(guid_str, "0x%" PRIx64, dump_guid);
90 TRACE_EVENT_NESTABLE_ASYNC_END2(MemoryDumpManager::kTraceCategory, 90 TRACE_EVENT_NESTABLE_ASYNC_END2(MemoryDumpManager::kTraceCategory,
91 "GlobalMemoryDump", TRACE_ID_LOCAL(dump_guid), 91 "GlobalMemoryDump", TRACE_ID_LOCAL(dump_guid),
92 "dump_guid", TRACE_STR_COPY(guid_str), 92 "dump_guid", TRACE_STR_COPY(guid_str),
93 "success", success); 93 "success", success);
94 94
95 if (!wrapped_callback.is_null()) { 95 if (!wrapped_callback.is_null()) {
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 443
444 AutoLock lock(lock_); 444 AutoLock lock(lock_);
445 dump_providers_for_polling_.erase(mdpinfo); 445 dump_providers_for_polling_.erase(mdpinfo);
446 DCHECK(!dump_providers_for_polling_.empty()) 446 DCHECK(!dump_providers_for_polling_.empty())
447 << "All polling MDPs cannot be unregistered."; 447 << "All polling MDPs cannot be unregistered.";
448 } 448 }
449 449
450 void MemoryDumpManager::RequestGlobalDump( 450 void MemoryDumpManager::RequestGlobalDump(
451 MemoryDumpType dump_type, 451 MemoryDumpType dump_type,
452 MemoryDumpLevelOfDetail level_of_detail, 452 MemoryDumpLevelOfDetail level_of_detail,
453 const MemoryDumpCallback& callback) { 453 const GlobalMemoryDumpCallback& callback) {
454 // Bail out immediately if tracing is not enabled at all or if the dump mode 454 // Bail out immediately if tracing is not enabled at all or if the dump mode
455 // is not allowed. 455 // is not allowed.
456 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_)) || 456 if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_)) ||
457 !IsDumpModeAllowed(level_of_detail)) { 457 !IsDumpModeAllowed(level_of_detail)) {
458 VLOG(1) << kLogPrefix << " failed because " << kTraceCategory 458 VLOG(1) << kLogPrefix << " failed because " << kTraceCategory
459 << " tracing category is not enabled or the requested dump mode is " 459 << " tracing category is not enabled or the requested dump mode is "
460 "not allowed by trace config."; 460 "not allowed by trace config.";
461 if (!callback.is_null()) 461 if (!callback.is_null())
462 callback.Run(0u /* guid */, false /* success */); 462 callback.Run(0u /* guid */, false /* success */);
463 return; 463 return;
464 } 464 }
465 465
466 const uint64_t guid = 466 const uint64_t guid =
467 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); 467 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext());
468 468
469 // Creates an async event to keep track of the global dump evolution. 469 // Creates an async event to keep track of the global dump evolution.
470 // The |wrapped_callback| will generate the ASYNC_END event and then invoke 470 // The |wrapped_callback| will generate the ASYNC_END event and then invoke
471 // the real |callback| provided by the caller. 471 // the real |callback| provided by the caller.
472 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( 472 TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
473 kTraceCategory, "GlobalMemoryDump", TRACE_ID_LOCAL(guid), "dump_type", 473 kTraceCategory, "GlobalMemoryDump", TRACE_ID_LOCAL(guid), "dump_type",
474 MemoryDumpTypeToString(dump_type), "level_of_detail", 474 MemoryDumpTypeToString(dump_type), "level_of_detail",
475 MemoryDumpLevelOfDetailToString(level_of_detail)); 475 MemoryDumpLevelOfDetailToString(level_of_detail));
476 MemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback); 476 GlobalMemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback);
477 477
478 // The delegate will coordinate the IPC broadcast and at some point invoke 478 // The delegate will coordinate the IPC broadcast and at some point invoke
479 // CreateProcessDump() to get a dump for the current process. 479 // CreateProcessDump() to get a dump for the current process.
480 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail}; 480 MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail};
481 delegate_->RequestGlobalMemoryDump(args, wrapped_callback); 481 delegate_->RequestGlobalMemoryDump(args, wrapped_callback);
482 } 482 }
483 483
484 void MemoryDumpManager::RequestGlobalDump( 484 void MemoryDumpManager::RequestGlobalDump(
485 MemoryDumpType dump_type, 485 MemoryDumpType dump_type,
486 MemoryDumpLevelOfDetail level_of_detail) { 486 MemoryDumpLevelOfDetail level_of_detail) {
487 RequestGlobalDump(dump_type, level_of_detail, MemoryDumpCallback()); 487 RequestGlobalDump(dump_type, level_of_detail, GlobalMemoryDumpCallback());
488 } 488 }
489 489
490 bool MemoryDumpManager::IsDumpProviderRegisteredForTesting( 490 bool MemoryDumpManager::IsDumpProviderRegisteredForTesting(
491 MemoryDumpProvider* provider) { 491 MemoryDumpProvider* provider) {
492 AutoLock lock(lock_); 492 AutoLock lock(lock_);
493 493
494 for (const auto& info : dump_providers_) { 494 for (const auto& info : dump_providers_) {
495 if (info->dump_provider == provider) 495 if (info->dump_provider == provider)
496 return true; 496 return true;
497 } 497 }
498 return false; 498 return false;
499 } 499 }
500 500
501 void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, 501 void MemoryDumpManager::CreateProcessDump(
502 const MemoryDumpCallback& callback) { 502 const MemoryDumpRequestArgs& args,
503 const ProcessMemoryDumpCallback& callback) {
503 char guid_str[20]; 504 char guid_str[20];
504 sprintf(guid_str, "0x%" PRIx64, args.dump_guid); 505 sprintf(guid_str, "0x%" PRIx64, args.dump_guid);
505 TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(kTraceCategory, "ProcessMemoryDump", 506 TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(kTraceCategory, "ProcessMemoryDump",
506 TRACE_ID_LOCAL(args.dump_guid), "dump_guid", 507 TRACE_ID_LOCAL(args.dump_guid), "dump_guid",
507 TRACE_STR_COPY(guid_str)); 508 TRACE_STR_COPY(guid_str));
508 509
509 // If argument filter is enabled then only background mode dumps should be 510 // If argument filter is enabled then only background mode dumps should be
510 // allowed. In case the trace config passed for background tracing session 511 // allowed. In case the trace config passed for background tracing session
511 // missed the allowed modes argument, it crashes here instead of creating 512 // missed the allowed modes argument, it crashes here instead of creating
512 // unexpected dumps. 513 // unexpected dumps.
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 callback_task_runner->PostTask( 756 callback_task_runner->PostTask(
756 FROM_HERE, Bind(&MemoryDumpManager::FinalizeDumpAndAddToTrace, 757 FROM_HERE, Bind(&MemoryDumpManager::FinalizeDumpAndAddToTrace,
757 Passed(&pmd_async_state))); 758 Passed(&pmd_async_state)));
758 return; 759 return;
759 } 760 }
760 761
761 TRACE_EVENT0(kTraceCategory, "MemoryDumpManager::FinalizeDumpAndAddToTrace"); 762 TRACE_EVENT0(kTraceCategory, "MemoryDumpManager::FinalizeDumpAndAddToTrace");
762 763
763 // The results struct to fill. 764 // The results struct to fill.
764 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 765 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
765 MemoryDumpCallbackResult result; 766 base::Optional<MemoryDumpCallbackResult> result_opt;
hjd 2017/04/06 11:18:45 Should we have #include "base/optional.h"?
Primiano Tucci (use gerrit) 2017/04/07 15:31:36 +1, IWYU (Include What You Use, i.e. don't depen d
fmeawad 2017/04/10 20:20:19 Done.
766 767
767 for (const auto& kv : pmd_async_state->process_dumps) { 768 for (const auto& kv : pmd_async_state->process_dumps) {
768 ProcessId pid = kv.first; // kNullProcessId for the current process. 769 ProcessId pid = kv.first; // kNullProcessId for the current process.
769 ProcessMemoryDump* process_memory_dump = kv.second.get(); 770 ProcessMemoryDump* process_memory_dump = kv.second.get();
770 std::unique_ptr<TracedValue> traced_value(new TracedValue); 771 std::unique_ptr<TracedValue> traced_value(new TracedValue);
771 process_memory_dump->AsValueInto(traced_value.get()); 772 process_memory_dump->AsValueInto(traced_value.get());
772 traced_value->SetString("level_of_detail", 773 traced_value->SetString("level_of_detail",
773 MemoryDumpLevelOfDetailToString( 774 MemoryDumpLevelOfDetailToString(
774 pmd_async_state->req_args.level_of_detail)); 775 pmd_async_state->req_args.level_of_detail));
775 const char* const event_name = 776 const char* const event_name =
(...skipping 11 matching lines...) Expand all
787 788
788 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 789 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
789 // Don't try to fill the struct in detailed mode since it is hard to avoid 790 // Don't try to fill the struct in detailed mode since it is hard to avoid
790 // double counting. 791 // double counting.
791 if (pmd_async_state->req_args.level_of_detail == 792 if (pmd_async_state->req_args.level_of_detail ==
792 MemoryDumpLevelOfDetail::DETAILED) 793 MemoryDumpLevelOfDetail::DETAILED)
793 continue; 794 continue;
794 795
795 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 796 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
796 if (pid == kNullProcessId) { 797 if (pid == kNullProcessId) {
798 MemoryDumpCallbackResult result;
797 result.chrome_dump.malloc_total_kb = 799 result.chrome_dump.malloc_total_kb =
798 GetDumpsSumKb("malloc", process_memory_dump); 800 GetDumpsSumKb("malloc", process_memory_dump);
799 result.chrome_dump.v8_total_kb = 801 result.chrome_dump.v8_total_kb =
800 GetDumpsSumKb("v8/*", process_memory_dump); 802 GetDumpsSumKb("v8/*", process_memory_dump);
801 803
802 // partition_alloc reports sizes for both allocated_objects and 804 // partition_alloc reports sizes for both allocated_objects and
803 // partitions. The memory allocated_objects uses is a subset of 805 // partitions. The memory allocated_objects uses is a subset of
804 // the partitions memory so to avoid double counting we only 806 // the partitions memory so to avoid double counting we only
805 // count partitions memory. 807 // count partitions memory.
806 result.chrome_dump.partition_alloc_total_kb = 808 result.chrome_dump.partition_alloc_total_kb =
807 GetDumpsSumKb("partition_alloc/partitions/*", process_memory_dump); 809 GetDumpsSumKb("partition_alloc/partitions/*", process_memory_dump);
808 result.chrome_dump.blink_gc_total_kb = 810 result.chrome_dump.blink_gc_total_kb =
809 GetDumpsSumKb("blink_gc", process_memory_dump); 811 GetDumpsSumKb("blink_gc", process_memory_dump);
812 result_opt = result;
810 } 813 }
811 } 814 }
812 815
813 bool tracing_still_enabled; 816 bool tracing_still_enabled;
814 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled); 817 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled);
815 if (!tracing_still_enabled) { 818 if (!tracing_still_enabled) {
816 pmd_async_state->dump_successful = false; 819 pmd_async_state->dump_successful = false;
817 VLOG(1) << kLogPrefix << " failed because tracing was disabled before" 820 VLOG(1) << kLogPrefix << " failed because tracing was disabled before"
818 << " the dump was completed"; 821 << " the dump was completed";
819 } 822 }
820 823
821 if (!pmd_async_state->callback.is_null()) { 824 if (!pmd_async_state->callback.is_null()) {
822 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful); 825 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful,
826 result_opt);
823 pmd_async_state->callback.Reset(); 827 pmd_async_state->callback.Reset();
824 } 828 }
825 829
826 TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump", 830 TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump",
827 TRACE_ID_LOCAL(dump_guid)); 831 TRACE_ID_LOCAL(dump_guid));
828 } 832 }
829 833
830 void MemoryDumpManager::OnTraceLogEnabled() { 834 void MemoryDumpManager::OnTraceLogEnabled() {
831 bool enabled; 835 bool enabled;
832 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled); 836 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 AutoLock lock(lock_); 957 AutoLock lock(lock_);
954 if (!session_state_) 958 if (!session_state_)
955 return false; 959 return false;
956 return session_state_->IsDumpModeAllowed(dump_mode); 960 return session_state_->IsDumpModeAllowed(dump_mode);
957 } 961 }
958 962
959 MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState( 963 MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
960 MemoryDumpRequestArgs req_args, 964 MemoryDumpRequestArgs req_args,
961 const MemoryDumpProviderInfo::OrderedSet& dump_providers, 965 const MemoryDumpProviderInfo::OrderedSet& dump_providers,
962 scoped_refptr<MemoryDumpSessionState> session_state, 966 scoped_refptr<MemoryDumpSessionState> session_state,
963 MemoryDumpCallback callback, 967 ProcessMemoryDumpCallback callback,
964 scoped_refptr<SingleThreadTaskRunner> dump_thread_task_runner) 968 scoped_refptr<SingleThreadTaskRunner> dump_thread_task_runner)
965 : req_args(req_args), 969 : req_args(req_args),
966 session_state(std::move(session_state)), 970 session_state(std::move(session_state)),
967 callback(callback), 971 callback(callback),
968 dump_successful(true), 972 dump_successful(true),
969 callback_task_runner(ThreadTaskRunnerHandle::Get()), 973 callback_task_runner(ThreadTaskRunnerHandle::Get()),
970 dump_thread_task_runner(std::move(dump_thread_task_runner)) { 974 dump_thread_task_runner(std::move(dump_thread_task_runner)) {
971 pending_dump_providers.reserve(dump_providers.size()); 975 pending_dump_providers.reserve(dump_providers.size());
972 pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend()); 976 pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend());
973 } 977 }
974 978
975 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { 979 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() {
976 } 980 }
977 981
978 ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState:: 982 ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState::
979 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid, 983 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid,
980 const MemoryDumpArgs& dump_args) { 984 const MemoryDumpArgs& dump_args) {
981 auto iter = process_dumps.find(pid); 985 auto iter = process_dumps.find(pid);
982 if (iter == process_dumps.end()) { 986 if (iter == process_dumps.end()) {
983 std::unique_ptr<ProcessMemoryDump> new_pmd( 987 std::unique_ptr<ProcessMemoryDump> new_pmd(
984 new ProcessMemoryDump(session_state, dump_args)); 988 new ProcessMemoryDump(session_state, dump_args));
985 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; 989 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
986 } 990 }
987 return iter->second.get(); 991 return iter->second.get();
988 } 992 }
989 993
990 } // namespace trace_event 994 } // namespace trace_event
991 } // namespace base 995 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698