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

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

Issue 2650863003: [tracing] Switch to new heap dump format. (Closed)
Patch Set: Fix StringDeduplicator::Insert Created 3 years, 9 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 <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/allocator/features.h" 10 #include "base/allocator/features.h"
11 #include "base/atomic_sequence_num.h" 11 #include "base/atomic_sequence_num.h"
12 #include "base/base_switches.h" 12 #include "base/base_switches.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/debug/alias.h" 15 #include "base/debug/alias.h"
16 #include "base/debug/debugging_flags.h" 16 #include "base/debug/debugging_flags.h"
17 #include "base/debug/stack_trace.h" 17 #include "base/debug/stack_trace.h"
18 #include "base/debug/thread_heap_usage_tracker.h" 18 #include "base/debug/thread_heap_usage_tracker.h"
19 #include "base/memory/ptr_util.h" 19 #include "base/memory/ptr_util.h"
20 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/trace_event/heap_profiler.h" 22 #include "base/trace_event/heap_profiler.h"
23 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" 23 #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
24 #include "base/trace_event/heap_profiler_event_filter.h" 24 #include "base/trace_event/heap_profiler_event_filter.h"
25 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" 25 #include "base/trace_event/heap_profiler_event_writer.h"
26 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
27 #include "base/trace_event/malloc_dump_provider.h" 26 #include "base/trace_event/malloc_dump_provider.h"
28 #include "base/trace_event/memory_dump_provider.h" 27 #include "base/trace_event/memory_dump_provider.h"
29 #include "base/trace_event/memory_dump_scheduler.h" 28 #include "base/trace_event/memory_dump_scheduler.h"
30 #include "base/trace_event/memory_dump_session_state.h" 29 #include "base/trace_event/memory_dump_session_state.h"
31 #include "base/trace_event/memory_infra_background_whitelist.h" 30 #include "base/trace_event/memory_infra_background_whitelist.h"
32 #include "base/trace_event/process_memory_dump.h" 31 #include "base/trace_event/process_memory_dump.h"
33 #include "base/trace_event/trace_event.h" 32 #include "base/trace_event/trace_event.h"
34 #include "base/trace_event/trace_event_argument.h" 33 #include "base/trace_event/trace_event_argument.h"
35 #include "build/build_config.h" 34 #include "build/build_config.h"
36 35
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 TRACE_EVENT_NESTABLE_ASYNC_END1( 82 TRACE_EVENT_NESTABLE_ASYNC_END1(
84 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", 83 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump",
85 TRACE_ID_MANGLE(dump_guid), "success", success); 84 TRACE_ID_MANGLE(dump_guid), "success", success);
86 85
87 if (!wrapped_callback.is_null()) { 86 if (!wrapped_callback.is_null()) {
88 wrapped_callback.Run(dump_guid, success); 87 wrapped_callback.Run(dump_guid, success);
89 wrapped_callback.Reset(); 88 wrapped_callback.Reset();
90 } 89 }
91 } 90 }
92 91
93 // Proxy class which wraps a ConvertableToTraceFormat owned by the
94 // |session_state| into a proxy object that can be added to the trace event log.
95 // This is to solve the problem that the MemoryDumpSessionState is refcounted
96 // but the tracing subsystem wants a std::unique_ptr<ConvertableToTraceFormat>.
97 template <typename T>
98 struct SessionStateConvertableProxy : public ConvertableToTraceFormat {
99 using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const;
100
101 SessionStateConvertableProxy(
102 scoped_refptr<MemoryDumpSessionState> session_state,
103 GetterFunctPtr getter_function)
104 : session_state(session_state), getter_function(getter_function) {}
105
106 void AppendAsTraceFormat(std::string* out) const override {
107 return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out);
108 }
109
110 void EstimateTraceMemoryOverhead(
111 TraceEventMemoryOverhead* overhead) override {
112 return (session_state.get()->*getter_function)()
113 ->EstimateTraceMemoryOverhead(overhead);
114 }
115
116 scoped_refptr<MemoryDumpSessionState> session_state;
117 GetterFunctPtr const getter_function;
118 };
119
120 } // namespace 92 } // namespace
121 93
122 // static 94 // static
123 const char* const MemoryDumpManager::kTraceCategory = 95 const char* const MemoryDumpManager::kTraceCategory =
124 TRACE_DISABLED_BY_DEFAULT("memory-infra"); 96 TRACE_DISABLED_BY_DEFAULT("memory-infra");
125 97
126 // static 98 // static
127 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; 99 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump";
128 100
129 // static 101 // static
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 std::move(traced_value)); 724 std::move(traced_value));
753 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( 725 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
754 TRACE_EVENT_PHASE_MEMORY_DUMP, 726 TRACE_EVENT_PHASE_MEMORY_DUMP,
755 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, 727 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name,
756 trace_event_internal::kGlobalScope, dump_guid, pid, 728 trace_event_internal::kGlobalScope, dump_guid, pid,
757 kTraceEventNumArgs, kTraceEventArgNames, 729 kTraceEventNumArgs, kTraceEventArgNames,
758 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, 730 kTraceEventArgTypes, nullptr /* arg_values */, &event_value,
759 TRACE_EVENT_FLAG_HAS_ID); 731 TRACE_EVENT_FLAG_HAS_ID);
760 } 732 }
761 733
734 const size_t kHeapProfileNumArgs = 1;
735 const char* kHeapProfileArgNames[] = {"data"};
736 const unsigned char kHeapProfileArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
737 for (const auto& kv : pmd_async_state->process_dumps) {
738 ProcessId pid = kv.first;
739 ProcessMemoryDump* process_memory_dump = kv.second.get();
740 if (pid != kNullProcessId) {
741 // We expect heap dumps only from the current process.
742 DCHECK(process_memory_dump->heap_dumps().empty());
743 continue;
744 }
745
746 auto event_data = ExportHeapProfileEventData(
747 process_memory_dump->heap_dumps(), *pmd_async_state->session_state);
748
749 std::unique_ptr<ConvertableToTraceFormat> values[kHeapProfileNumArgs] = {
750 std::move(event_data)};
751 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
752 TRACE_EVENT_PHASE_SAMPLE,
753 TraceLog::GetCategoryGroupEnabled(kTraceCategory), "heap_profile",
754 trace_event_internal::kGlobalScope, dump_guid, pid, kHeapProfileNumArgs,
755 kHeapProfileArgNames, kHeapProfileArgTypes, nullptr /* arg_values */,
756 values, TRACE_EVENT_FLAG_HAS_ID);
ssid 2017/03/13 03:38:00 +1 to add this to same trace event as above.
757 }
758
762 bool tracing_still_enabled; 759 bool tracing_still_enabled;
763 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled); 760 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled);
764 if (!tracing_still_enabled) { 761 if (!tracing_still_enabled) {
765 pmd_async_state->dump_successful = false; 762 pmd_async_state->dump_successful = false;
766 VLOG(1) << kLogPrefix << " failed because tracing was disabled before" 763 VLOG(1) << kLogPrefix << " failed because tracing was disabled before"
767 << " the dump was completed"; 764 << " the dump was completed";
768 } 765 }
769 766
770 if (!pmd_async_state->callback.is_null()) { 767 if (!pmd_async_state->callback.is_null()) {
771 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful); 768 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful);
(...skipping 25 matching lines...) Expand all
797 const TraceConfig& trace_config = 794 const TraceConfig& trace_config =
798 TraceLog::GetInstance()->GetCurrentTraceConfig(); 795 TraceLog::GetInstance()->GetCurrentTraceConfig();
799 const TraceConfig::MemoryDumpConfig& memory_dump_config = 796 const TraceConfig::MemoryDumpConfig& memory_dump_config =
800 trace_config.memory_dump_config(); 797 trace_config.memory_dump_config();
801 scoped_refptr<MemoryDumpSessionState> session_state = 798 scoped_refptr<MemoryDumpSessionState> session_state =
802 new MemoryDumpSessionState; 799 new MemoryDumpSessionState;
803 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes); 800 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes);
804 session_state->set_heap_profiler_breakdown_threshold_bytes( 801 session_state->set_heap_profiler_breakdown_threshold_bytes(
805 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes); 802 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
806 if (heap_profiling_enabled_) { 803 if (heap_profiling_enabled_) {
807 // If heap profiling is enabled, the stack frame deduplicator and type name 804 // TODO(dskiba): support continuous mode
808 // deduplicator will be in use. Add a metadata events to write the frames 805 DCHECK(trace_config.GetTraceRecordMode() != RECORD_CONTINUOUSLY)
809 // and type IDs. 806 << "Heap profile format is incremental and doesn't yet support "
810 session_state->SetStackFrameDeduplicator( 807 << "continuous mode.";
811 WrapUnique(new StackFrameDeduplicator)); 808 session_state->CreateDeduplicators();
812
813 session_state->SetTypeNameDeduplicator(
814 WrapUnique(new TypeNameDeduplicator));
815
816 TRACE_EVENT_API_ADD_METADATA_EVENT(
817 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames",
818 "stackFrames",
819 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>(
820 session_state, &MemoryDumpSessionState::stack_frame_deduplicator));
821
822 TRACE_EVENT_API_ADD_METADATA_EVENT(
823 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames",
824 "typeNames",
825 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>(
826 session_state, &MemoryDumpSessionState::type_name_deduplicator));
827 } 809 }
828 810
829 std::unique_ptr<MemoryDumpScheduler> dump_scheduler( 811 std::unique_ptr<MemoryDumpScheduler> dump_scheduler(
830 new MemoryDumpScheduler(this, dump_thread->task_runner())); 812 new MemoryDumpScheduler(this, dump_thread->task_runner()));
831 DCHECK_LE(memory_dump_config.triggers.size(), 3u); 813 DCHECK_LE(memory_dump_config.triggers.size(), 3u);
832 for (const auto& trigger : memory_dump_config.triggers) { 814 for (const auto& trigger : memory_dump_config.triggers) {
833 if (!session_state->IsDumpModeAllowed(trigger.level_of_detail)) { 815 if (!session_state->IsDumpModeAllowed(trigger.level_of_detail)) {
834 NOTREACHED(); 816 NOTREACHED();
835 continue; 817 continue;
836 } 818 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 if (iter == process_dumps.end()) { 947 if (iter == process_dumps.end()) {
966 std::unique_ptr<ProcessMemoryDump> new_pmd( 948 std::unique_ptr<ProcessMemoryDump> new_pmd(
967 new ProcessMemoryDump(session_state, dump_args)); 949 new ProcessMemoryDump(session_state, dump_args));
968 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; 950 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
969 } 951 }
970 return iter->second.get(); 952 return iter->second.get();
971 } 953 }
972 954
973 } // namespace trace_event 955 } // namespace trace_event
974 } // namespace base 956 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698