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

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

Issue 2820433005: memory-infra: Start disentangling tracing from memory-infra (Closed)
Patch Set: add todo 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 18 matching lines...) Expand all
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_stack_frame_deduplicator.h" 31 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
32 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" 32 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
33 #include "base/trace_event/malloc_dump_provider.h" 33 #include "base/trace_event/malloc_dump_provider.h"
34 #include "base/trace_event/memory_dump_provider.h" 34 #include "base/trace_event/memory_dump_provider.h"
35 #include "base/trace_event/memory_dump_scheduler.h" 35 #include "base/trace_event/memory_dump_scheduler.h"
36 #include "base/trace_event/memory_dump_session_state.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/process_memory_dump.h" 40 #include "base/trace_event/process_memory_dump.h"
40 #include "base/trace_event/trace_event.h" 41 #include "base/trace_event/trace_event.h"
41 #include "base/trace_event/trace_event_argument.h" 42 #include "base/trace_event/trace_event_argument.h"
42 #include "build/build_config.h" 43 #include "build/build_config.h"
43 44
44 #if defined(OS_ANDROID) 45 #if defined(OS_ANDROID)
45 #include "base/trace_event/java_heap_dump_provider_android.h" 46 #include "base/trace_event/java_heap_dump_provider_android.h"
46 #endif 47 #endif
47 48
48 namespace base { 49 namespace base {
49 namespace trace_event { 50 namespace trace_event {
50 51
51 namespace { 52 namespace {
52 53
53 const int kTraceEventNumArgs = 1;
54 const char* kTraceEventArgNames[] = {"dumps"};
55 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
56
57 StaticAtomicSequenceNumber g_next_guid; 54 StaticAtomicSequenceNumber g_next_guid;
58 MemoryDumpManager* g_instance_for_testing = nullptr; 55 MemoryDumpManager* g_instance_for_testing = nullptr;
59 56
60 // The list of names of dump providers that are blacklisted from strict thread 57 // The list of names of dump providers that are blacklisted from strict thread
61 // affinity check on unregistration. These providers could potentially cause 58 // affinity check on unregistration. These providers could potentially cause
62 // crashes on build bots if they do not unregister on right thread. 59 // crashes on build bots if they do not unregister on right thread.
63 // TODO(ssid): Fix all the dump providers to unregister if needed and clear the 60 // TODO(ssid): Fix all the dump providers to unregister if needed and clear the
64 // blacklist, crbug.com/643438. 61 // blacklist, crbug.com/643438.
65 const char* const kStrictThreadCheckBlacklist[] = { 62 const char* const kStrictThreadCheckBlacklist[] = {
66 "ClientDiscardableSharedMemoryManager", 63 "ClientDiscardableSharedMemoryManager",
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 189
193 // At this point the command line may not be initialized but we try to 190 // At this point the command line may not be initialized but we try to
194 // enable the heap profiler to capture allocations as soon as possible. 191 // enable the heap profiler to capture allocations as soon as possible.
195 EnableHeapProfilingIfNeeded(); 192 EnableHeapProfilingIfNeeded();
196 193
197 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist), 194 strict_thread_check_blacklist_.insert(std::begin(kStrictThreadCheckBlacklist),
198 std::end(kStrictThreadCheckBlacklist)); 195 std::end(kStrictThreadCheckBlacklist));
199 } 196 }
200 197
201 MemoryDumpManager::~MemoryDumpManager() { 198 MemoryDumpManager::~MemoryDumpManager() {
202 TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
203 } 199 }
204 200
205 void MemoryDumpManager::EnableHeapProfilingIfNeeded() { 201 void MemoryDumpManager::EnableHeapProfilingIfNeeded() {
206 if (heap_profiling_enabled_) 202 if (heap_profiling_enabled_)
207 return; 203 return;
208 204
209 if (!CommandLine::InitializedForCurrentProcess() || 205 if (!CommandLine::InitializedForCurrentProcess() ||
210 !CommandLine::ForCurrentProcess()->HasSwitch( 206 !CommandLine::ForCurrentProcess()->HasSwitch(
211 switches::kEnableHeapProfiling)) 207 switches::kEnableHeapProfiling))
212 return; 208 return;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 279
284 TraceConfig::EventFilters filters; 280 TraceConfig::EventFilters filters;
285 filters.push_back(heap_profiler_filter_config); 281 filters.push_back(heap_profiler_filter_config);
286 TraceConfig filtering_trace_config; 282 TraceConfig filtering_trace_config;
287 filtering_trace_config.SetEventFilters(filters); 283 filtering_trace_config.SetEventFilters(filters);
288 284
289 TraceLog::GetInstance()->SetEnabled(filtering_trace_config, 285 TraceLog::GetInstance()->SetEnabled(filtering_trace_config,
290 TraceLog::FILTERING_MODE); 286 TraceLog::FILTERING_MODE);
291 } 287 }
292 288
293 // If tracing was enabled before initializing MemoryDumpManager, we missed the 289 // TODO(hjd): Move out of MDM. See: crbug.com/703184
294 // OnTraceLogEnabled() event. Synthetize it so we can late-join the party. 290 tracing_observer_ =
295 // IsEnabled is called before adding observer to avoid calling 291 MakeUnique<MemoryTracingObserver>(TraceLog::GetInstance(), this);
296 // OnTraceLogEnabled twice.
297 bool is_tracing_already_enabled = TraceLog::GetInstance()->IsEnabled();
298 TraceLog::GetInstance()->AddEnabledStateObserver(this);
299 if (is_tracing_already_enabled)
300 OnTraceLogEnabled();
301 } 292 }
302 293
303 void MemoryDumpManager::RegisterDumpProvider( 294 void MemoryDumpManager::RegisterDumpProvider(
304 MemoryDumpProvider* mdp, 295 MemoryDumpProvider* mdp,
305 const char* name, 296 const char* name,
306 scoped_refptr<SingleThreadTaskRunner> task_runner, 297 scoped_refptr<SingleThreadTaskRunner> task_runner,
307 MemoryDumpProvider::Options options) { 298 MemoryDumpProvider::Options options) {
308 options.dumps_on_single_thread_task_runner = true; 299 options.dumps_on_single_thread_task_runner = true;
309 RegisterDumpProviderInternal(mdp, name, std::move(task_runner), options); 300 RegisterDumpProviderInternal(mdp, name, std::move(task_runner), options);
310 } 301 }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 const ProcessMemoryDump* pmd) { 707 const ProcessMemoryDump* pmd) {
717 uint64_t sum = 0; 708 uint64_t sum = 0;
718 for (const auto& kv : pmd->allocator_dumps()) { 709 for (const auto& kv : pmd->allocator_dumps()) {
719 auto name = StringPiece(kv.first); 710 auto name = StringPiece(kv.first);
720 if (MatchPattern(name, pattern)) 711 if (MatchPattern(name, pattern))
721 sum += kv.second->GetSize(); 712 sum += kv.second->GetSize();
722 } 713 }
723 return sum / 1024; 714 return sum / 1024;
724 } 715 }
725 716
726 // static
727 void MemoryDumpManager::FinalizeDumpAndAddToTrace( 717 void MemoryDumpManager::FinalizeDumpAndAddToTrace(
728 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) { 718 std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) {
729 HEAP_PROFILER_SCOPED_IGNORE; 719 HEAP_PROFILER_SCOPED_IGNORE;
730 DCHECK(pmd_async_state->pending_dump_providers.empty()); 720 DCHECK(pmd_async_state->pending_dump_providers.empty());
731 const uint64_t dump_guid = pmd_async_state->req_args.dump_guid; 721 const uint64_t dump_guid = pmd_async_state->req_args.dump_guid;
732 if (!pmd_async_state->callback_task_runner->BelongsToCurrentThread()) { 722 if (!pmd_async_state->callback_task_runner->BelongsToCurrentThread()) {
733 scoped_refptr<SingleThreadTaskRunner> callback_task_runner = 723 scoped_refptr<SingleThreadTaskRunner> callback_task_runner =
734 pmd_async_state->callback_task_runner; 724 pmd_async_state->callback_task_runner;
735 callback_task_runner->PostTask( 725 callback_task_runner->PostTask(
736 FROM_HERE, BindOnce(&MemoryDumpManager::FinalizeDumpAndAddToTrace, 726 FROM_HERE, BindOnce(&MemoryDumpManager::FinalizeDumpAndAddToTrace,
737 Passed(&pmd_async_state))); 727 Unretained(this), Passed(&pmd_async_state)));
738 return; 728 return;
739 } 729 }
740 730
741 TRACE_EVENT0(kTraceCategory, "MemoryDumpManager::FinalizeDumpAndAddToTrace"); 731 TRACE_EVENT0(kTraceCategory, "MemoryDumpManager::FinalizeDumpAndAddToTrace");
742 732
743 // The results struct to fill. 733 // The results struct to fill.
744 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 734 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
745 base::Optional<MemoryDumpCallbackResult> result; 735 base::Optional<MemoryDumpCallbackResult> result;
736
737 bool dump_successful = pmd_async_state->dump_successful;
738
746 for (const auto& kv : pmd_async_state->process_dumps) { 739 for (const auto& kv : pmd_async_state->process_dumps) {
747 ProcessId pid = kv.first; // kNullProcessId for the current process. 740 ProcessId pid = kv.first; // kNullProcessId for the current process.
748 ProcessMemoryDump* process_memory_dump = kv.second.get(); 741 ProcessMemoryDump* process_memory_dump = kv.second.get();
749 std::unique_ptr<TracedValue> traced_value(new TracedValue);
750 process_memory_dump->AsValueInto(traced_value.get());
751 traced_value->SetString("level_of_detail",
752 MemoryDumpLevelOfDetailToString(
753 pmd_async_state->req_args.level_of_detail));
754 const char* const event_name =
755 MemoryDumpTypeToString(pmd_async_state->req_args.dump_type);
756 742
757 std::unique_ptr<ConvertableToTraceFormat> event_value( 743 bool added_to_trace = tracing_observer_->AddDumpToTraceIfEnabled(
758 std::move(traced_value)); 744 &pmd_async_state->req_args, pid, process_memory_dump);
759 TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( 745
760 TRACE_EVENT_PHASE_MEMORY_DUMP, 746 dump_successful = dump_successful && added_to_trace;
761 TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name,
762 trace_event_internal::kGlobalScope, dump_guid, pid,
763 kTraceEventNumArgs, kTraceEventArgNames,
764 kTraceEventArgTypes, nullptr /* arg_values */, &event_value,
765 TRACE_EVENT_FLAG_HAS_ID);
766 747
767 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 748 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
768 // Don't try to fill the struct in detailed mode since it is hard to avoid 749 // Don't try to fill the struct in detailed mode since it is hard to avoid
769 // double counting. 750 // double counting.
770 if (pmd_async_state->req_args.level_of_detail == 751 if (pmd_async_state->req_args.level_of_detail ==
771 MemoryDumpLevelOfDetail::DETAILED) 752 MemoryDumpLevelOfDetail::DETAILED)
772 continue; 753 continue;
773 if (!result.has_value()) 754 if (!result.has_value())
774 result = MemoryDumpCallbackResult(); 755 result = MemoryDumpCallbackResult();
775 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203 756 // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
(...skipping 11 matching lines...) Expand all
787 GetDumpsSumKb("partition_alloc/partitions/*", process_memory_dump); 768 GetDumpsSumKb("partition_alloc/partitions/*", process_memory_dump);
788 result->chrome_dump.blink_gc_total_kb = 769 result->chrome_dump.blink_gc_total_kb =
789 GetDumpsSumKb("blink_gc", process_memory_dump); 770 GetDumpsSumKb("blink_gc", process_memory_dump);
790 FillOsDumpFromProcessMemoryDump(process_memory_dump, &result->os_dump); 771 FillOsDumpFromProcessMemoryDump(process_memory_dump, &result->os_dump);
791 } else { 772 } else {
792 auto& os_dump = result->extra_processes_dump[pid]; 773 auto& os_dump = result->extra_processes_dump[pid];
793 FillOsDumpFromProcessMemoryDump(process_memory_dump, &os_dump); 774 FillOsDumpFromProcessMemoryDump(process_memory_dump, &os_dump);
794 } 775 }
795 } 776 }
796 777
797 bool tracing_still_enabled;
798 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &tracing_still_enabled);
799 if (!tracing_still_enabled) {
800 pmd_async_state->dump_successful = false;
801 VLOG(1) << kLogPrefix << " failed because tracing was disabled before"
802 << " the dump was completed";
803 }
804
805 if (!pmd_async_state->callback.is_null()) { 778 if (!pmd_async_state->callback.is_null()) {
806 pmd_async_state->callback.Run(dump_guid, pmd_async_state->dump_successful, 779 pmd_async_state->callback.Run(dump_guid, dump_successful, result);
807 result);
808 pmd_async_state->callback.Reset(); 780 pmd_async_state->callback.Reset();
809 } 781 }
810 782
811 TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump", 783 TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump",
812 TRACE_ID_LOCAL(dump_guid)); 784 TRACE_ID_LOCAL(dump_guid));
813 } 785 }
814 786
815 void MemoryDumpManager::OnTraceLogEnabled() { 787 void MemoryDumpManager::Enable(
816 bool enabled; 788 const TraceConfig::MemoryDumpConfig& memory_dump_config) {
817 TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled);
818 if (!enabled)
819 return;
820
821 // Initialize the TraceLog for the current thread. This is to avoid that the
822 // TraceLog memory dump provider is registered lazily in the PostTask() below
823 // while the |lock_| is taken;
824 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported();
825
826 // Spin-up the thread used to invoke unbound dump providers. 789 // Spin-up the thread used to invoke unbound dump providers.
827 std::unique_ptr<Thread> dump_thread(new Thread("MemoryInfra")); 790 std::unique_ptr<Thread> dump_thread(new Thread("MemoryInfra"));
828 if (!dump_thread->Start()) { 791 if (!dump_thread->Start()) {
829 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; 792 LOG(ERROR) << "Failed to start the memory-infra thread for tracing";
830 return; 793 return;
831 } 794 }
832 795
833 const TraceConfig& trace_config =
834 TraceLog::GetInstance()->GetCurrentTraceConfig();
835 const TraceConfig::MemoryDumpConfig& memory_dump_config =
836 trace_config.memory_dump_config();
837 scoped_refptr<MemoryDumpSessionState> session_state = 796 scoped_refptr<MemoryDumpSessionState> session_state =
838 new MemoryDumpSessionState; 797 new MemoryDumpSessionState;
839 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes); 798 session_state->SetAllowedDumpModes(memory_dump_config.allowed_dump_modes);
840 session_state->set_heap_profiler_breakdown_threshold_bytes( 799 session_state->set_heap_profiler_breakdown_threshold_bytes(
841 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes); 800 memory_dump_config.heap_profiler_options.breakdown_threshold_bytes);
842 if (heap_profiling_enabled_) { 801 if (heap_profiling_enabled_) {
843 // If heap profiling is enabled, the stack frame deduplicator and type name 802 // If heap profiling is enabled, the stack frame deduplicator and type name
844 // deduplicator will be in use. Add a metadata events to write the frames 803 // deduplicator will be in use. Add a metadata events to write the frames
845 // and type IDs. 804 // and type IDs.
846 session_state->SetStackFrameDeduplicator( 805 session_state->SetStackFrameDeduplicator(
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 } 870 }
912 } 871 }
913 872
914 // Only coordinator process triggers periodic global memory dumps. 873 // Only coordinator process triggers periodic global memory dumps.
915 if (delegate_->IsCoordinator() && !periodic_config.triggers.empty()) { 874 if (delegate_->IsCoordinator() && !periodic_config.triggers.empty()) {
916 MemoryDumpScheduler::GetInstance()->Start(periodic_config, 875 MemoryDumpScheduler::GetInstance()->Start(periodic_config,
917 dump_thread_->task_runner()); 876 dump_thread_->task_runner());
918 } 877 }
919 } 878 }
920 879
921 void MemoryDumpManager::OnTraceLogDisabled() { 880 void MemoryDumpManager::Disable() {
922 // There might be a memory dump in progress while this happens. Therefore, 881 // There might be a memory dump in progress while this happens. Therefore,
923 // ensure that the MDM state which depends on the tracing enabled / disabled 882 // ensure that the MDM state which depends on the tracing enabled / disabled
924 // state is always accessed by the dumping methods holding the |lock_|. 883 // state is always accessed by the dumping methods holding the |lock_|.
925 if (!subtle::NoBarrier_Load(&memory_tracing_enabled_)) 884 if (!subtle::NoBarrier_Load(&memory_tracing_enabled_))
926 return; 885 return;
927 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); 886 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
928 std::unique_ptr<Thread> dump_thread; 887 std::unique_ptr<Thread> dump_thread;
929 { 888 {
930 AutoLock lock(lock_); 889 AutoLock lock(lock_);
931 MemoryDumpScheduler::GetInstance()->Stop(); 890 MemoryDumpScheduler::GetInstance()->Stop();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 if (iter == process_dumps.end()) { 932 if (iter == process_dumps.end()) {
974 std::unique_ptr<ProcessMemoryDump> new_pmd( 933 std::unique_ptr<ProcessMemoryDump> new_pmd(
975 new ProcessMemoryDump(session_state, dump_args)); 934 new ProcessMemoryDump(session_state, dump_args));
976 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; 935 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
977 } 936 }
978 return iter->second.get(); 937 return iter->second.get();
979 } 938 }
980 939
981 } // namespace trace_event 940 } // namespace trace_event
982 } // namespace base 941 } // 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