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

Side by Side Diff: content/browser/tracing/tracing_controller_impl.cc

Issue 2067793004: [memory-infra] Add support for queueing memory dump requests in the browser process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address final comments Created 4 years, 5 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
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #include "content/browser/tracing/tracing_controller_impl.h" 4 #include "content/browser/tracing/tracing_controller_impl.h"
5 5
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/cpu.h" 7 #include "base/cpu.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/guid.h" 9 #include "base/guid.h"
10 #include "base/json/string_escape.h" 10 #include "base/json/string_escape.h"
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 if (it != pending_trace_log_status_filters_.end()) { 554 if (it != pending_trace_log_status_filters_.end()) {
555 BrowserThread::PostTask( 555 BrowserThread::PostTask(
556 BrowserThread::UI, FROM_HERE, 556 BrowserThread::UI, FROM_HERE,
557 base::Bind(&TracingControllerImpl::OnTraceLogStatusReply, 557 base::Bind(&TracingControllerImpl::OnTraceLogStatusReply,
558 base::Unretained(this), 558 base::Unretained(this),
559 base::RetainedRef(trace_message_filter), 559 base::RetainedRef(trace_message_filter),
560 base::trace_event::TraceLogStatus())); 560 base::trace_event::TraceLogStatus()));
561 } 561 }
562 } 562 }
563 if (pending_memory_dump_ack_count_ > 0) { 563 if (pending_memory_dump_ack_count_ > 0) {
564 DCHECK(!queued_memory_dump_requests_.empty());
564 TraceMessageFilterSet::const_iterator it = 565 TraceMessageFilterSet::const_iterator it =
565 pending_memory_dump_filters_.find(trace_message_filter); 566 pending_memory_dump_filters_.find(trace_message_filter);
566 if (it != pending_memory_dump_filters_.end()) { 567 if (it != pending_memory_dump_filters_.end()) {
567 BrowserThread::PostTask( 568 BrowserThread::PostTask(
568 BrowserThread::UI, FROM_HERE, 569 BrowserThread::UI, FROM_HERE,
569 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse, 570 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse,
570 base::Unretained(this), 571 base::Unretained(this),
571 base::RetainedRef(trace_message_filter), 572 base::RetainedRef(trace_message_filter),
572 pending_memory_dump_guid_, false /* success */)); 573 queued_memory_dump_requests_.front().args.dump_guid,
574 false /* success */));
573 } 575 }
574 } 576 }
575 trace_message_filters_.erase(trace_message_filter); 577 trace_message_filters_.erase(trace_message_filter);
576 } 578 }
577 579
578 void TracingControllerImpl::AddTracingAgent(const std::string& agent_name) { 580 void TracingControllerImpl::AddTracingAgent(const std::string& agent_name) {
579 #if defined(OS_CHROMEOS) 581 #if defined(OS_CHROMEOS)
580 auto debug_daemon = 582 auto debug_daemon =
581 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); 583 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
582 if (agent_name == debug_daemon->GetTracingAgentName()) { 584 if (agent_name == debug_daemon->GetTracingAgentName()) {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 void TracingControllerImpl::RequestGlobalMemoryDump( 915 void TracingControllerImpl::RequestGlobalMemoryDump(
914 const base::trace_event::MemoryDumpRequestArgs& args, 916 const base::trace_event::MemoryDumpRequestArgs& args,
915 const base::trace_event::MemoryDumpCallback& callback) { 917 const base::trace_event::MemoryDumpCallback& callback) {
916 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 918 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
917 BrowserThread::PostTask( 919 BrowserThread::PostTask(
918 BrowserThread::UI, FROM_HERE, 920 BrowserThread::UI, FROM_HERE,
919 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump, 921 base::Bind(&TracingControllerImpl::RequestGlobalMemoryDump,
920 base::Unretained(this), args, callback)); 922 base::Unretained(this), args, callback));
921 return; 923 return;
922 } 924 }
923 // Abort if another dump is already in progress. 925
924 if (pending_memory_dump_guid_) { 926 bool another_dump_already_in_progress = !queued_memory_dump_requests_.empty();
925 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix 927
926 << " (" << args.dump_guid << ") aborted because another dump (" 928 // If this is a periodic memory dump request and there already is another
927 << pending_memory_dump_guid_ << ") is in progress"; 929 // request in the queue with the same level of detail, there's no point in
928 if (!callback.is_null()) 930 // enqueuing this request.
929 callback.Run(args.dump_guid, false /* success */); 931 if (another_dump_already_in_progress &&
932 args.dump_type == base::trace_event::MemoryDumpType::PERIODIC_INTERVAL) {
933 for (const auto& request : queued_memory_dump_requests_) {
934 if (request.args.level_of_detail == args.level_of_detail) {
935 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " ("
936 << base::trace_event::MemoryDumpTypeToString(args.dump_type)
937 << ") skipped because another dump request with the same "
938 "level of detail ("
939 << base::trace_event::MemoryDumpLevelOfDetailToString(
940 args.level_of_detail)
941 << ") is already in the queue";
942 if (!callback.is_null())
943 callback.Run(args.dump_guid, false /* success */);
944 return;
945 }
946 }
947 }
948
949 queued_memory_dump_requests_.emplace_back(args, callback);
950
951 // If another dump is already in progress, this dump will automatically be
952 // scheduled when the other dump finishes.
953 if (another_dump_already_in_progress)
930 return; 954 return;
931 } 955
956 PerformNextQueuedGlobalMemoryDump();
957 }
958
959 void TracingControllerImpl::PerformNextQueuedGlobalMemoryDump() {
960 DCHECK_CURRENTLY_ON(BrowserThread::UI);
961 DCHECK(!queued_memory_dump_requests_.empty());
962 const base::trace_event::MemoryDumpRequestArgs& args =
963 queued_memory_dump_requests_.front().args;
932 964
933 // Count myself (local trace) in pending_memory_dump_ack_count_, acked by 965 // Count myself (local trace) in pending_memory_dump_ack_count_, acked by
934 // OnBrowserProcessMemoryDumpDone(). 966 // OnBrowserProcessMemoryDumpDone().
935 pending_memory_dump_ack_count_ = trace_message_filters_.size() + 1; 967 pending_memory_dump_ack_count_ = trace_message_filters_.size() + 1;
936 pending_memory_dump_filters_.clear(); 968 pending_memory_dump_filters_.clear();
937 pending_memory_dump_guid_ = args.dump_guid;
938 pending_memory_dump_callback_ = callback;
939 failed_memory_dump_count_ = 0; 969 failed_memory_dump_count_ = 0;
940 970
941 MemoryDumpManagerDelegate::CreateProcessDump( 971 MemoryDumpManagerDelegate::CreateProcessDump(
942 args, base::Bind(&TracingControllerImpl::OnBrowserProcessMemoryDumpDone, 972 args, base::Bind(&TracingControllerImpl::OnBrowserProcessMemoryDumpDone,
943 base::Unretained(this))); 973 base::Unretained(this)));
944 974
945 // If there are no child processes we are just done. 975 // If there are no child processes we are just done.
946 if (pending_memory_dump_ack_count_ == 1) 976 if (pending_memory_dump_ack_count_ == 1)
947 return; 977 return;
948 978
949 pending_memory_dump_filters_ = trace_message_filters_; 979 pending_memory_dump_filters_ = trace_message_filters_;
950 980
951 for (const scoped_refptr<TraceMessageFilter>& tmf : trace_message_filters_) 981 for (const scoped_refptr<TraceMessageFilter>& tmf : trace_message_filters_)
952 tmf->SendProcessMemoryDumpRequest(args); 982 tmf->SendProcessMemoryDumpRequest(args);
953 } 983 }
954 984
985 TracingControllerImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest(
986 const base::trace_event::MemoryDumpRequestArgs& args,
987 const base::trace_event::MemoryDumpCallback& callback)
988 : args(args), callback(callback) {}
989
990 TracingControllerImpl::QueuedMemoryDumpRequest::~QueuedMemoryDumpRequest() {}
991
955 uint64_t TracingControllerImpl::GetTracingProcessId() const { 992 uint64_t TracingControllerImpl::GetTracingProcessId() const {
956 return ChildProcessHost::kBrowserTracingProcessId; 993 return ChildProcessHost::kBrowserTracingProcessId;
957 } 994 }
958 995
959 void TracingControllerImpl::AddTraceMessageFilterObserver( 996 void TracingControllerImpl::AddTraceMessageFilterObserver(
960 TraceMessageFilterObserver* observer) { 997 TraceMessageFilterObserver* observer) {
961 DCHECK_CURRENTLY_ON(BrowserThread::UI); 998 DCHECK_CURRENTLY_ON(BrowserThread::UI);
962 trace_message_filter_observers_.AddObserver(observer); 999 trace_message_filter_observers_.AddObserver(observer);
963 1000
964 for (auto& filter : trace_message_filters_) 1001 for (auto& filter : trace_message_filters_)
(...skipping 19 matching lines...) Expand all
984 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse, 1021 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse,
985 base::Unretained(this), 1022 base::Unretained(this),
986 base::RetainedRef(trace_message_filter), dump_guid, 1023 base::RetainedRef(trace_message_filter), dump_guid,
987 success)); 1024 success));
988 return; 1025 return;
989 } 1026 }
990 1027
991 TraceMessageFilterSet::iterator it = 1028 TraceMessageFilterSet::iterator it =
992 pending_memory_dump_filters_.find(trace_message_filter); 1029 pending_memory_dump_filters_.find(trace_message_filter);
993 1030
994 if (pending_memory_dump_guid_ != dump_guid || 1031 DCHECK(!queued_memory_dump_requests_.empty());
1032 if (queued_memory_dump_requests_.front().args.dump_guid != dump_guid ||
995 it == pending_memory_dump_filters_.end()) { 1033 it == pending_memory_dump_filters_.end()) {
996 DLOG(WARNING) << "Received unexpected memory dump response: " << dump_guid; 1034 DLOG(WARNING) << "Received unexpected memory dump response: " << dump_guid;
997 return; 1035 return;
998 } 1036 }
999 1037
1000 DCHECK_GT(pending_memory_dump_ack_count_, 0); 1038 DCHECK_GT(pending_memory_dump_ack_count_, 0);
1001 --pending_memory_dump_ack_count_; 1039 --pending_memory_dump_ack_count_;
1002 pending_memory_dump_filters_.erase(it); 1040 pending_memory_dump_filters_.erase(it);
1003 if (!success) { 1041 if (!success) {
1004 ++failed_memory_dump_count_; 1042 ++failed_memory_dump_count_;
(...skipping 13 matching lines...) Expand all
1018 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix 1056 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
1019 << " aborted on the current process"; 1057 << " aborted on the current process";
1020 } 1058 }
1021 FinalizeGlobalMemoryDumpIfAllProcessesReplied(); 1059 FinalizeGlobalMemoryDumpIfAllProcessesReplied();
1022 } 1060 }
1023 1061
1024 void TracingControllerImpl::FinalizeGlobalMemoryDumpIfAllProcessesReplied() { 1062 void TracingControllerImpl::FinalizeGlobalMemoryDumpIfAllProcessesReplied() {
1025 if (pending_memory_dump_ack_count_ > 0) 1063 if (pending_memory_dump_ack_count_ > 0)
1026 return; 1064 return;
1027 1065
1028 DCHECK_NE(0u, pending_memory_dump_guid_); 1066 DCHECK(!queued_memory_dump_requests_.empty());
1029 const bool global_success = failed_memory_dump_count_ == 0; 1067 {
1030 if (!pending_memory_dump_callback_.is_null()) { 1068 const auto& callback = queued_memory_dump_requests_.front().callback;
1031 pending_memory_dump_callback_.Run(pending_memory_dump_guid_, 1069 if (!callback.is_null()) {
1032 global_success); 1070 const bool global_success = failed_memory_dump_count_ == 0;
1033 pending_memory_dump_callback_.Reset(); 1071 callback.Run(queued_memory_dump_requests_.front().args.dump_guid,
1072 global_success);
1073 }
1034 } 1074 }
1035 pending_memory_dump_guid_ = 0; 1075 queued_memory_dump_requests_.pop_front();
1076
1077 // Schedule the next queued dump (if applicable).
1078 if (!queued_memory_dump_requests_.empty()) {
1079 BrowserThread::PostTask(
1080 BrowserThread::UI, FROM_HERE,
1081 base::Bind(&TracingControllerImpl::PerformNextQueuedGlobalMemoryDump,
1082 base::Unretained(this)));
1083 }
1036 } 1084 }
1037 1085
1038 } // namespace content 1086 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/tracing_controller_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698