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/allocator/features.h" | 10 #include "base/allocator/features.h" |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 TRACE_EVENT_NESTABLE_ASYNC_END1( | 87 TRACE_EVENT_NESTABLE_ASYNC_END1( |
88 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", | 88 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", |
89 TRACE_ID_MANGLE(dump_guid), "success", success); | 89 TRACE_ID_MANGLE(dump_guid), "success", success); |
90 | 90 |
91 if (!wrapped_callback.is_null()) { | 91 if (!wrapped_callback.is_null()) { |
92 wrapped_callback.Run(dump_guid, success); | 92 wrapped_callback.Run(dump_guid, success); |
93 wrapped_callback.Reset(); | 93 wrapped_callback.Reset(); |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
97 // Proxy class which wraps a ConvertableToTraceFormat owned by the | |
98 // |session_state| into a proxy object that can be added to the trace event log. | |
99 // This is to solve the problem that the MemoryDumpSessionState is refcounted | |
100 // but the tracing subsystem wants a std::unique_ptr<ConvertableToTraceFormat>. | |
101 template <typename T> | |
102 struct SessionStateConvertableProxy : public ConvertableToTraceFormat { | |
103 using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const; | |
104 | |
105 SessionStateConvertableProxy( | |
106 scoped_refptr<MemoryDumpSessionState> session_state, | |
107 GetterFunctPtr getter_function) | |
108 : session_state(session_state), getter_function(getter_function) {} | |
109 | |
110 void AppendAsTraceFormat(std::string* out) const override { | |
111 return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out); | |
112 } | |
113 | |
114 void EstimateTraceMemoryOverhead( | |
115 TraceEventMemoryOverhead* overhead) override { | |
116 return (session_state.get()->*getter_function)() | |
117 ->EstimateTraceMemoryOverhead(overhead); | |
118 } | |
119 | |
120 scoped_refptr<MemoryDumpSessionState> session_state; | |
121 GetterFunctPtr const getter_function; | |
122 }; | |
123 | |
124 } // namespace | 97 } // namespace |
125 | 98 |
126 // static | 99 // static |
127 const char* const MemoryDumpManager::kTraceCategory = | 100 const char* const MemoryDumpManager::kTraceCategory = |
128 TRACE_DISABLED_BY_DEFAULT("memory-infra"); | 101 TRACE_DISABLED_BY_DEFAULT("memory-infra"); |
129 | 102 |
130 // static | 103 // static |
131 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; | 104 const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump"; |
132 | 105 |
133 // static | 106 // static |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
727 std::move(traced_value)); | 700 std::move(traced_value)); |
728 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( | 701 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( |
729 TRACE_EVENT_PHASE_MEMORY_DUMP, | 702 TRACE_EVENT_PHASE_MEMORY_DUMP, |
730 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, | 703 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name, |
731 trace_event_internal::kGlobalScope, dump_guid, pid, | 704 trace_event_internal::kGlobalScope, dump_guid, pid, |
732 kTraceEventNumArgs, kTraceEventArgNames, | 705 kTraceEventNumArgs, kTraceEventArgNames, |
733 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, | 706 kTraceEventArgTypes, nullptr /* arg_values */, &event_value, |
734 TRACE_EVENT_FLAG_HAS_ID); | 707 TRACE_EVENT_FLAG_HAS_ID); |
735 } | 708 } |
736 | 709 |
710 const size_t kHeapDumpNumArgs = 1; | |
711 const char* kHeapDumpArgNames[] = {"data"}; | |
712 const unsigned char kHeapDumpArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; | |
713 for (const auto& kv : pmd_async_state->process_dumps) { | |
714 ProcessId pid = kv.first; | |
715 ProcessMemoryDump* process_memory_dump = kv.second.get(); | |
716 if (pid != kNullProcessId) { | |
717 // We expect heap dumps only from the current process. | |
718 DCHECK(process_memory_dump->heap_dumps().empty()); | |
719 continue; | |
720 } | |
721 | |
722 auto heap_dump_value = MakeUnique<TracedValue>(); | |
723 | |
724 // Add version specifying format of the data below. | |
725 heap_dump_value->SetInteger("version", 1); | |
Primiano Tucci (use gerrit)
2017/02/17 17:07:05
I think that historically we avoided any sort of v
DmitrySkiba
2017/02/23 07:17:19
My position is exactly the opposite - versioning i
hjd
2017/02/23 12:33:27
I was motivated to ask Dmitry to add the version k
| |
726 | |
727 // Add "malloc", "blink_gc", etc. nodes, each containing a dump. | |
728 for (const auto& name_and_dump : process_memory_dump->heap_dumps()) { | |
729 heap_dump_value->SetValueWithCopiedName(name_and_dump.first.c_str(), | |
730 *name_and_dump.second); | |
731 } | |
732 | |
733 // Add "maps" node. | |
734 if (auto* session_state = pmd_async_state->session_state.get()) { | |
735 heap_dump_value->BeginDictionary("maps"); | |
736 if (auto* deduplicator = session_state->type_name_deduplicator()) { | |
737 heap_dump_value->BeginArray("types"); | |
738 deduplicator->AppendIncrementally(&*heap_dump_value); | |
739 heap_dump_value->EndArray(); | |
740 } | |
741 if (auto* deduplicator = session_state->stack_frame_deduplicator()) { | |
742 heap_dump_value->BeginArray("nodes"); | |
743 deduplicator->AppendIncrementally(&*heap_dump_value); | |
744 heap_dump_value->EndArray(); | |
745 } | |
746 heap_dump_value->EndDictionary(); | |
747 } | |
748 | |
749 std::unique_ptr<ConvertableToTraceFormat> values[kHeapDumpNumArgs] = { | |
750 std::move(heap_dump_value)}; | |
751 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( | |
752 TRACE_EVENT_PHASE_SAMPLE, | |
753 TraceLog::GetCategoryGroupEnabled(kTraceCategory), "heap_profile", | |
Primiano Tucci (use gerrit)
2017/02/17 17:07:05
this is the only thing where I'm not fully sure. W
DmitrySkiba
2017/02/23 07:17:19
I think we discussed this exact concern several ti
hjd
2017/02/23 12:33:27
As I mentioned before if we eventually want to sha
| |
754 trace_event_internal::kGlobalScope, dump_guid, pid, kHeapDumpNumArgs, | |
755 kHeapDumpArgNames, kHeapDumpArgTypes, nullptr /* arg_values */, values, | |
756 TRACE_EVENT_FLAG_HAS_ID); | |
757 } | |
758 | |
737 bool tracing_still_enabled; | 759 bool tracing_still_enabled; |
738 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled); | 760 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled); |
739 if (!tracing_still_enabled) { | 761 if (!tracing_still_enabled) { |
740 pmd_async_state->dump_successful = false; | 762 pmd_async_state->dump_successful = false; |
741 VLOG(1) << kLogPrefix << " failed because tracing was disabled before" | 763 VLOG(1) << kLogPrefix << " failed because tracing was disabled before" |
742 << " the dump was completed"; | 764 << " the dump was completed"; |
743 } | 765 } |
744 | 766 |
745 if (!pmd_async_state->callback.is_null()) { | 767 if (!pmd_async_state->callback.is_null()) { |
746 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 29 matching lines...) Expand all Loading... | |
776 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config()); | 798 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config()); |
777 if (heap_profiling_enabled_) { | 799 if (heap_profiling_enabled_) { |
778 // If heap profiling is enabled, the stack frame deduplicator and type name | 800 // If heap profiling is enabled, the stack frame deduplicator and type name |
779 // deduplicator will be in use. Add a metadata events to write the frames | 801 // deduplicator will be in use. Add a metadata events to write the frames |
780 // and type IDs. | 802 // and type IDs. |
781 session_state->SetStackFrameDeduplicator( | 803 session_state->SetStackFrameDeduplicator( |
782 WrapUnique(new StackFrameDeduplicator)); | 804 WrapUnique(new StackFrameDeduplicator)); |
783 | 805 |
784 session_state->SetTypeNameDeduplicator( | 806 session_state->SetTypeNameDeduplicator( |
785 WrapUnique(new TypeNameDeduplicator)); | 807 WrapUnique(new TypeNameDeduplicator)); |
786 | |
787 TRACE_EVENT_API_ADD_METADATA_EVENT( | |
788 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", | |
789 "stackFrames", | |
790 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>( | |
791 session_state, &MemoryDumpSessionState::stack_frame_deduplicator)); | |
792 | |
793 TRACE_EVENT_API_ADD_METADATA_EVENT( | |
794 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", | |
795 "typeNames", | |
796 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( | |
797 session_state, &MemoryDumpSessionState::type_name_deduplicator)); | |
798 } | 808 } |
799 | 809 |
800 { | 810 { |
801 AutoLock lock(lock_); | 811 AutoLock lock(lock_); |
802 | 812 |
803 DCHECK(delegate_); // At this point we must have a delegate. | 813 DCHECK(delegate_); // At this point we must have a delegate. |
804 session_state_ = session_state; | 814 session_state_ = session_state; |
805 | 815 |
806 DCHECK(!dump_thread_); | 816 DCHECK(!dump_thread_); |
807 dump_thread_ = std::move(dump_thread); | 817 dump_thread_ = std::move(dump_thread); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
993 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) | 1003 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0) |
994 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; | 1004 level_of_detail = MemoryDumpLevelOfDetail::DETAILED; |
995 ++periodic_dumps_count_; | 1005 ++periodic_dumps_count_; |
996 | 1006 |
997 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 1007 MemoryDumpManager::GetInstance()->RequestGlobalDump( |
998 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); | 1008 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail); |
999 } | 1009 } |
1000 | 1010 |
1001 } // namespace trace_event | 1011 } // namespace trace_event |
1002 } // namespace base | 1012 } // namespace base |
OLD | NEW |