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

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

Issue 2861133002: memory-infra: Move dump level check to observer and rename session state (Closed)
Patch Set: move comment Created 3 years, 7 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 10 matching lines...) Expand all
21 #include "base/debug/thread_heap_usage_tracker.h" 21 #include "base/debug/thread_heap_usage_tracker.h"
22 #include "base/memory/ptr_util.h" 22 #include "base/memory/ptr_util.h"
23 #include "base/optional.h" 23 #include "base/optional.h"
24 #include "base/strings/pattern.h" 24 #include "base/strings/pattern.h"
25 #include "base/strings/string_piece.h" 25 #include "base/strings/string_piece.h"
26 #include "base/threading/thread.h" 26 #include "base/threading/thread.h"
27 #include "base/threading/thread_task_runner_handle.h" 27 #include "base/threading/thread_task_runner_handle.h"
28 #include "base/trace_event/heap_profiler.h" 28 #include "base/trace_event/heap_profiler.h"
29 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" 29 #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
30 #include "base/trace_event/heap_profiler_event_filter.h" 30 #include "base/trace_event/heap_profiler_event_filter.h"
31 #include "base/trace_event/heap_profiler_serialization_state.h"
31 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" 32 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
32 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" 33 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
33 #include "base/trace_event/malloc_dump_provider.h" 34 #include "base/trace_event/malloc_dump_provider.h"
34 #include "base/trace_event/memory_dump_provider.h" 35 #include "base/trace_event/memory_dump_provider.h"
35 #include "base/trace_event/memory_dump_scheduler.h" 36 #include "base/trace_event/memory_dump_scheduler.h"
36 #include "base/trace_event/memory_dump_session_state.h"
37 #include "base/trace_event/memory_infra_background_whitelist.h" 37 #include "base/trace_event/memory_infra_background_whitelist.h"
38 #include "base/trace_event/memory_peak_detector.h" 38 #include "base/trace_event/memory_peak_detector.h"
39 #include "base/trace_event/memory_tracing_observer.h" 39 #include "base/trace_event/memory_tracing_observer.h"
40 #include "base/trace_event/process_memory_dump.h" 40 #include "base/trace_event/process_memory_dump.h"
41 #include "base/trace_event/trace_event.h" 41 #include "base/trace_event/trace_event.h"
42 #include "base/trace_event/trace_event_argument.h" 42 #include "base/trace_event/trace_event_argument.h"
43 #include "build/build_config.h" 43 #include "build/build_config.h"
44 44
45 #if defined(OS_ANDROID) 45 #if defined(OS_ANDROID)
46 #include "base/trace_event/java_heap_dump_provider_android.h" 46 #include "base/trace_event/java_heap_dump_provider_android.h"
(...skipping 29 matching lines...) Expand all
76 const ProcessMemoryDump* pmd, 76 const ProcessMemoryDump* pmd,
77 MemoryDumpCallbackResult::OSMemDump* osDump) { 77 MemoryDumpCallbackResult::OSMemDump* osDump) {
78 if (pmd->has_process_totals()) { 78 if (pmd->has_process_totals()) {
79 const ProcessMemoryTotals* totals = pmd->process_totals(); 79 const ProcessMemoryTotals* totals = pmd->process_totals();
80 osDump->resident_set_kb = totals->resident_set_bytes() / 1024; 80 osDump->resident_set_kb = totals->resident_set_bytes() / 1024;
81 osDump->platform_private_footprint = totals->GetPlatformPrivateFootprint(); 81 osDump->platform_private_footprint = totals->GetPlatformPrivateFootprint();
82 } 82 }
83 } 83 }
84 84
85 // Proxy class which wraps a ConvertableToTraceFormat owned by the 85 // Proxy class which wraps a ConvertableToTraceFormat owned by the
86 // |session_state| into a proxy object that can be added to the trace event log. 86 // |heap_profiler_serialization_state| into a proxy object that can be added to
87 // This is to solve the problem that the MemoryDumpSessionState is refcounted 87 // the trace event log. This is to solve the problem that the
88 // but the tracing subsystem wants a std::unique_ptr<ConvertableToTraceFormat>. 88 // HeapProfilerSerializationState is refcounted but the tracing subsystem wants
89 // a std::unique_ptr<ConvertableToTraceFormat>.
89 template <typename T> 90 template <typename T>
90 struct SessionStateConvertableProxy : public ConvertableToTraceFormat { 91 struct SessionStateConvertableProxy : public ConvertableToTraceFormat {
91 using GetterFunctPtr = T* (MemoryDumpSessionState::*)() const; 92 using GetterFunctPtr = T* (HeapProfilerSerializationState::*)() const;
92 93
93 SessionStateConvertableProxy( 94 SessionStateConvertableProxy(scoped_refptr<HeapProfilerSerializationState>
94 scoped_refptr<MemoryDumpSessionState> session_state, 95 heap_profiler_serialization_state,
95 GetterFunctPtr getter_function) 96 GetterFunctPtr getter_function)
96 : session_state(session_state), getter_function(getter_function) {} 97 : heap_profiler_serialization_state(heap_profiler_serialization_state),
98 getter_function(getter_function) {}
97 99
98 void AppendAsTraceFormat(std::string* out) const override { 100 void AppendAsTraceFormat(std::string* out) const override {
99 return (session_state.get()->*getter_function)()->AppendAsTraceFormat(out); 101 return (heap_profiler_serialization_state.get()->*getter_function)()
102 ->AppendAsTraceFormat(out);
100 } 103 }
101 104
102 void EstimateTraceMemoryOverhead( 105 void EstimateTraceMemoryOverhead(
103 TraceEventMemoryOverhead* overhead) override { 106 TraceEventMemoryOverhead* overhead) override {
104 return (session_state.get()->*getter_function)() 107 return (heap_profiler_serialization_state.get()->*getter_function)()
105 ->EstimateTraceMemoryOverhead(overhead); 108 ->EstimateTraceMemoryOverhead(overhead);
106 } 109 }
107 110
108 scoped_refptr<MemoryDumpSessionState> session_state; 111 scoped_refptr<HeapProfilerSerializationState>
112 heap_profiler_serialization_state;
109 GetterFunctPtr const getter_function; 113 GetterFunctPtr const getter_function;
110 }; 114 };
111 115
112 void OnPeakDetected(MemoryDumpLevelOfDetail level_of_detail) { 116 void OnPeakDetected(MemoryDumpLevelOfDetail level_of_detail) {
113 MemoryDumpManager::GetInstance()->RequestGlobalDump( 117 MemoryDumpManager::GetInstance()->RequestGlobalDump(
114 MemoryDumpType::PEAK_MEMORY_USAGE, level_of_detail); 118 MemoryDumpType::PEAK_MEMORY_USAGE, level_of_detail);
115 } 119 }
116 120
117 void OnPeriodicSchedulerTick(MemoryDumpLevelOfDetail level_of_detail) { 121 void OnPeriodicSchedulerTick(MemoryDumpLevelOfDetail level_of_detail) {
118 MemoryDumpManager::GetInstance()->RequestGlobalDump( 122 MemoryDumpManager::GetInstance()->RequestGlobalDump(
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 (*mdp_iter)->disabled = true; 404 (*mdp_iter)->disabled = true;
401 dump_providers_.erase(mdp_iter); 405 dump_providers_.erase(mdp_iter);
402 } 406 }
403 407
404 void MemoryDumpManager::RequestGlobalDump( 408 void MemoryDumpManager::RequestGlobalDump(
405 MemoryDumpType dump_type, 409 MemoryDumpType dump_type,
406 MemoryDumpLevelOfDetail level_of_detail, 410 MemoryDumpLevelOfDetail level_of_detail,
407 const GlobalMemoryDumpCallback& callback) { 411 const GlobalMemoryDumpCallback& callback) {
408 // Bail out immediately if tracing is not enabled at all or if the dump mode 412 // Bail out immediately if tracing is not enabled at all or if the dump mode
409 // is not allowed. 413 // is not allowed.
410 if (!UNLIKELY(subtle::NoBarrier_Load(&is_enabled_)) || 414 if (!UNLIKELY(subtle::NoBarrier_Load(&is_enabled_))) {
411 !IsDumpModeAllowed(level_of_detail)) {
ssid 2017/05/05 18:18:33 Hm , if we remove this check and also remove is_en
412 VLOG(1) << kLogPrefix << " failed because " << kTraceCategory 415 VLOG(1) << kLogPrefix << " failed because " << kTraceCategory
413 << " tracing category is not enabled or the requested dump mode is " 416 << " tracing category is not enabled.";
414 "not allowed by trace config.";
415 if (!callback.is_null()) 417 if (!callback.is_null())
416 callback.Run(0u /* guid */, false /* success */); 418 callback.Run(0u /* guid */, false /* success */);
417 return; 419 return;
418 } 420 }
419 421
420 const uint64_t guid = 422 const uint64_t guid =
421 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext()); 423 TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext());
422 424
423 // Creates an async event to keep track of the global dump evolution. 425 // Creates an async event to keep track of the global dump evolution.
424 // The |wrapped_callback| will generate the ASYNC_END event and then invoke 426 // The |wrapped_callback| will generate the ASYNC_END event and then invoke
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 ->GetCurrentTraceConfig() 495 ->GetCurrentTraceConfig()
494 .IsArgumentFilterEnabled()) { 496 .IsArgumentFilterEnabled()) {
495 CHECK_EQ(MemoryDumpLevelOfDetail::BACKGROUND, args.level_of_detail); 497 CHECK_EQ(MemoryDumpLevelOfDetail::BACKGROUND, args.level_of_detail);
496 } 498 }
497 499
498 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state; 500 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state;
499 { 501 {
500 AutoLock lock(lock_); 502 AutoLock lock(lock_);
501 503
502 pmd_async_state.reset(new ProcessMemoryDumpAsyncState( 504 pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
503 args, dump_providers_, session_state_, callback, 505 args, dump_providers_, heap_profiler_serialization_state_, callback,
504 GetOrCreateBgTaskRunnerLocked())); 506 GetOrCreateBgTaskRunnerLocked()));
505 507
506 // Safety check to prevent reaching here without calling RequestGlobalDump,
507 // with disallowed modes. If |session_state_| is null then tracing is
508 // disabled.
509 CHECK(!session_state_ ||
510 session_state_->IsDumpModeAllowed(args.level_of_detail));
511
512 // If enabled, holds back the peak detector resetting its estimation window. 508 // If enabled, holds back the peak detector resetting its estimation window.
513 MemoryPeakDetector::GetInstance()->Throttle(); 509 MemoryPeakDetector::GetInstance()->Throttle();
514 } 510 }
515 511
516 // Start the process dump. This involves task runner hops as specified by the 512 // Start the process dump. This involves task runner hops as specified by the
517 // MemoryDumpProvider(s) in RegisterDumpProvider()). 513 // MemoryDumpProvider(s) in RegisterDumpProvider()).
518 SetupNextMemoryDump(std::move(pmd_async_state)); 514 SetupNextMemoryDump(std::move(pmd_async_state));
519 } 515 }
520 516
521 // PostTask InvokeOnMemoryDump() to the dump provider's sequenced task runner. A 517 // PostTask InvokeOnMemoryDump() to the dump provider's sequenced task runner. A
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 pmd_async_state->callback.Run(dump_guid, dump_successful, result); 764 pmd_async_state->callback.Run(dump_guid, dump_successful, result);
769 pmd_async_state->callback.Reset(); 765 pmd_async_state->callback.Reset();
770 } 766 }
771 767
772 TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump", 768 TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump",
773 TRACE_ID_LOCAL(dump_guid)); 769 TRACE_ID_LOCAL(dump_guid));
774 } 770 }
775 771
776 void MemoryDumpManager::Enable( 772 void MemoryDumpManager::Enable(
777 const TraceConfig::MemoryDumpConfig& memory_dump_config) { 773 const TraceConfig::MemoryDumpConfig& memory_dump_config) {
778 774 scoped_refptr<HeapProfilerSerializationState>
779 scoped_refptr<MemoryDumpSessionState> session_state = 775 heap_profiler_serialization_state = new HeapProfilerSerializationState;
780 new MemoryDumpSessionState; 776 heap_profiler_serialization_state
781 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes); 777 ->set_heap_profiler_breakdown_threshold_bytes(
782 session_state->set_heap_profiler_breakdown_threshold_bytes( 778 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
783 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
784 if (heap_profiling_enabled_) { 779 if (heap_profiling_enabled_) {
785 // If heap profiling is enabled, the stack frame deduplicator and type name 780 // If heap profiling is enabled, the stack frame deduplicator and type name
786 // deduplicator will be in use. Add a metadata events to write the frames 781 // deduplicator will be in use. Add a metadata events to write the frames
787 // and type IDs. 782 // and type IDs.
788 session_state->SetStackFrameDeduplicator( 783 heap_profiler_serialization_state->SetStackFrameDeduplicator(
789 WrapUnique(new StackFrameDeduplicator)); 784 WrapUnique(new StackFrameDeduplicator));
790 785
791 session_state->SetTypeNameDeduplicator( 786 heap_profiler_serialization_state->SetTypeNameDeduplicator(
792 WrapUnique(new TypeNameDeduplicator)); 787 WrapUnique(new TypeNameDeduplicator));
793 788
794 TRACE_EVENT_API_ADD_METADATA_EVENT( 789 TRACE_EVENT_API_ADD_METADATA_EVENT(
795 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", 790 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames",
796 "stackFrames", 791 "stackFrames",
797 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>( 792 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>(
798 session_state, &MemoryDumpSessionState::stack_frame_deduplicator)); 793 heap_profiler_serialization_state,
794 &HeapProfilerSerializationState::stack_frame_deduplicator));
799 795
800 TRACE_EVENT_API_ADD_METADATA_EVENT( 796 TRACE_EVENT_API_ADD_METADATA_EVENT(
801 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", 797 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames",
802 "typeNames", 798 "typeNames",
803 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( 799 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>(
804 session_state, &MemoryDumpSessionState::type_name_deduplicator)); 800 heap_profiler_serialization_state,
801 &HeapProfilerSerializationState::type_name_deduplicator));
805 } 802 }
806 803
807 AutoLock lock(lock_); 804 AutoLock lock(lock_);
808 805
809 // At this point we must have the ability to request global dumps. 806 // At this point we must have the ability to request global dumps.
810 DCHECK(!request_dump_function_.is_null()); 807 DCHECK(!request_dump_function_.is_null());
811 session_state_ = session_state; 808 heap_profiler_serialization_state_ = heap_profiler_serialization_state;
812 809
813 subtle::NoBarrier_Store(&is_enabled_, 1); 810 subtle::NoBarrier_Store(&is_enabled_, 1);
814 811
815 MemoryDumpScheduler::Config periodic_config; 812 MemoryDumpScheduler::Config periodic_config;
816 bool peak_detector_configured = false; 813 bool peak_detector_configured = false;
817 for (const auto& trigger : memory_dump_config.triggers) { 814 for (const auto& trigger : memory_dump_config.triggers) {
818 if (!session_state_->IsDumpModeAllowed(trigger.level_of_detail)) {
819 NOTREACHED();
820 continue;
821 }
822 if (trigger.trigger_type == MemoryDumpType::PERIODIC_INTERVAL) { 815 if (trigger.trigger_type == MemoryDumpType::PERIODIC_INTERVAL) {
823 if (periodic_config.triggers.empty()) { 816 if (periodic_config.triggers.empty()) {
824 periodic_config.callback = BindRepeating(&OnPeriodicSchedulerTick); 817 periodic_config.callback = BindRepeating(&OnPeriodicSchedulerTick);
825 } 818 }
826 periodic_config.triggers.push_back( 819 periodic_config.triggers.push_back(
827 {trigger.level_of_detail, trigger.min_time_between_dumps_ms}); 820 {trigger.level_of_detail, trigger.min_time_between_dumps_ms});
828 } else if (trigger.trigger_type == MemoryDumpType::PEAK_MEMORY_USAGE) { 821 } else if (trigger.trigger_type == MemoryDumpType::PEAK_MEMORY_USAGE) {
829 // At most one peak trigger is allowed. 822 // At most one peak trigger is allowed.
830 CHECK(!peak_detector_configured); 823 CHECK(!peak_detector_configured);
831 peak_detector_configured = true; 824 peak_detector_configured = true;
(...skipping 30 matching lines...) Expand all
862 // There might be a memory dump in progress while this happens. Therefore, 855 // There might be a memory dump in progress while this happens. Therefore,
863 // ensure that the MDM state which depends on the tracing enabled / disabled 856 // ensure that the MDM state which depends on the tracing enabled / disabled
864 // state is always accessed by the dumping methods holding the |lock_|. 857 // state is always accessed by the dumping methods holding the |lock_|.
865 if (!subtle::NoBarrier_Load(&is_enabled_)) 858 if (!subtle::NoBarrier_Load(&is_enabled_))
866 return; 859 return;
867 subtle::NoBarrier_Store(&is_enabled_, 0); 860 subtle::NoBarrier_Store(&is_enabled_, 0);
868 { 861 {
869 AutoLock lock(lock_); 862 AutoLock lock(lock_);
870 MemoryDumpScheduler::GetInstance()->Stop(); 863 MemoryDumpScheduler::GetInstance()->Stop();
871 MemoryPeakDetector::GetInstance()->TearDown(); 864 MemoryPeakDetector::GetInstance()->TearDown();
872 session_state_ = nullptr; 865 heap_profiler_serialization_state_ = nullptr;
873 } 866 }
874 } 867 }
875 868
876 bool MemoryDumpManager::IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode) {
877 AutoLock lock(lock_);
878 if (!session_state_)
879 return false;
880 return session_state_->IsDumpModeAllowed(dump_mode);
881 }
882
883 MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState( 869 MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
884 MemoryDumpRequestArgs req_args, 870 MemoryDumpRequestArgs req_args,
885 const MemoryDumpProviderInfo::OrderedSet& dump_providers, 871 const MemoryDumpProviderInfo::OrderedSet& dump_providers,
886 scoped_refptr<MemoryDumpSessionState> session_state, 872 scoped_refptr<HeapProfilerSerializationState>
873 heap_profiler_serialization_state,
887 ProcessMemoryDumpCallback callback, 874 ProcessMemoryDumpCallback callback,
888 scoped_refptr<SequencedTaskRunner> dump_thread_task_runner) 875 scoped_refptr<SequencedTaskRunner> dump_thread_task_runner)
889 : req_args(req_args), 876 : req_args(req_args),
890 session_state(std::move(session_state)), 877 heap_profiler_serialization_state(
878 std::move(heap_profiler_serialization_state)),
891 callback(callback), 879 callback(callback),
892 dump_successful(true), 880 dump_successful(true),
893 callback_task_runner(ThreadTaskRunnerHandle::Get()), 881 callback_task_runner(ThreadTaskRunnerHandle::Get()),
894 dump_thread_task_runner(std::move(dump_thread_task_runner)) { 882 dump_thread_task_runner(std::move(dump_thread_task_runner)) {
895 pending_dump_providers.reserve(dump_providers.size()); 883 pending_dump_providers.reserve(dump_providers.size());
896 pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend()); 884 pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend());
897 } 885 }
898 886
899 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() { 887 MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() {
900 } 888 }
901 889
902 ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState:: 890 ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState::
903 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid, 891 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid,
904 const MemoryDumpArgs& dump_args) { 892 const MemoryDumpArgs& dump_args) {
905 auto iter = process_dumps.find(pid); 893 auto iter = process_dumps.find(pid);
906 if (iter == process_dumps.end()) { 894 if (iter == process_dumps.end()) {
907 std::unique_ptr<ProcessMemoryDump> new_pmd( 895 std::unique_ptr<ProcessMemoryDump> new_pmd(
908 new ProcessMemoryDump(session_state, dump_args)); 896 new ProcessMemoryDump(heap_profiler_serialization_state, dump_args));
909 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; 897 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
910 } 898 }
911 return iter->second.get(); 899 return iter->second.get();
912 } 900 }
913 901
914 } // namespace trace_event 902 } // namespace trace_event
915 } // namespace base 903 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/memory_dump_manager.h ('k') | base/trace_event/memory_dump_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698