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

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: Addressed review comments Created 4 years, 6 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 (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();
Primiano Tucci (use gerrit) 2016/06/23 11:09:16 I really love this perfectly touching the 80th col
petrcermak 2016/06/24 10:49:57 Ack :-)
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 without a callback and there
Primiano Tucci (use gerrit) 2016/06/23 11:09:16 remove the "without a callback" part. It is not tr
petrcermak 2016/06/24 10:49:57 Done.
927 << pending_memory_dump_guid_ << ") is in progress"; 929 // already is another request in the queue with the same level of detail,
928 if (!callback.is_null()) 930 // there's no point in enqueuing this request.
929 callback.Run(args.dump_guid, false /* success */); 931 if (another_dump_already_in_progress) {
Primiano Tucci (use gerrit) 2016/06/23 11:09:16 why not if (another... && dump_type == ). Would re
petrcermak 2016/06/24 10:49:57 Done.
932 if (args.dump_type ==
933 base::trace_event::MemoryDumpType::PERIODIC_INTERVAL) {
934 const auto requested_level_of_detail = args.level_of_detail;
Primiano Tucci (use gerrit) 2016/06/23 11:09:16 not sure this variable buys you anything really
petrcermak 2016/06/24 10:49:57 I removed it.
935 for (const auto& request : queued_memory_dump_requests_) {
936 if (request.args.level_of_detail == requested_level_of_detail) {
937 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " ("
938 << base::trace_event::MemoryDumpTypeToString(args.dump_type)
939 << ") skipped because another dump request with the same "
940 "level of detail ("
941 << base::trace_event::MemoryDumpLevelOfDetailToString(
942 requested_level_of_detail)
943 << ") is already in the queue";
944 if (!callback.is_null())
945 callback.Run(args.dump_guid, false /* success */);
946 return;
947 }
948 }
949 }
950 }
951
952 queued_memory_dump_requests_.emplace_back(args, callback);
953
954 // If another dump is already in progress, this dump will automatically be
955 // scheduled when the other dump finishes.
956 if (another_dump_already_in_progress)
930 return; 957 return;
931 } 958
959 PerformGlobalMemoryDump();
960 }
961
962 void TracingControllerImpl::PerformGlobalMemoryDump() {
963 DCHECK_CURRENTLY_ON(BrowserThread::UI);
964 DCHECK(!queued_memory_dump_requests_.empty());
965 const base::trace_event::MemoryDumpRequestArgs& args =
966 queued_memory_dump_requests_.front().args;
932 967
933 // Count myself (local trace) in pending_memory_dump_ack_count_, acked by 968 // Count myself (local trace) in pending_memory_dump_ack_count_, acked by
934 // OnBrowserProcessMemoryDumpDone(). 969 // OnBrowserProcessMemoryDumpDone().
935 pending_memory_dump_ack_count_ = trace_message_filters_.size() + 1; 970 pending_memory_dump_ack_count_ = trace_message_filters_.size() + 1;
936 pending_memory_dump_filters_.clear(); 971 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; 972 failed_memory_dump_count_ = 0;
940 973
941 MemoryDumpManagerDelegate::CreateProcessDump( 974 MemoryDumpManagerDelegate::CreateProcessDump(
942 args, base::Bind(&TracingControllerImpl::OnBrowserProcessMemoryDumpDone, 975 args, base::Bind(&TracingControllerImpl::OnBrowserProcessMemoryDumpDone,
943 base::Unretained(this))); 976 base::Unretained(this)));
944 977
945 // If there are no child processes we are just done. 978 // If there are no child processes we are just done.
946 if (pending_memory_dump_ack_count_ == 1) 979 if (pending_memory_dump_ack_count_ == 1)
947 return; 980 return;
948 981
949 pending_memory_dump_filters_ = trace_message_filters_; 982 pending_memory_dump_filters_ = trace_message_filters_;
950 983
951 for (const scoped_refptr<TraceMessageFilter>& tmf : trace_message_filters_) 984 for (const scoped_refptr<TraceMessageFilter>& tmf : trace_message_filters_)
952 tmf->SendProcessMemoryDumpRequest(args); 985 tmf->SendProcessMemoryDumpRequest(args);
953 } 986 }
954 987
988 TracingControllerImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest(
989 const base::trace_event::MemoryDumpRequestArgs& args,
990 const base::trace_event::MemoryDumpCallback& callback)
991 : args(args), callback(callback) {}
992
993 TracingControllerImpl::QueuedMemoryDumpRequest::~QueuedMemoryDumpRequest() {}
994
955 uint64_t TracingControllerImpl::GetTracingProcessId() const { 995 uint64_t TracingControllerImpl::GetTracingProcessId() const {
956 return ChildProcessHost::kBrowserTracingProcessId; 996 return ChildProcessHost::kBrowserTracingProcessId;
957 } 997 }
958 998
959 void TracingControllerImpl::AddTraceMessageFilterObserver( 999 void TracingControllerImpl::AddTraceMessageFilterObserver(
960 TraceMessageFilterObserver* observer) { 1000 TraceMessageFilterObserver* observer) {
961 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1001 DCHECK_CURRENTLY_ON(BrowserThread::UI);
962 trace_message_filter_observers_.AddObserver(observer); 1002 trace_message_filter_observers_.AddObserver(observer);
963 1003
964 for (auto& filter : trace_message_filters_) 1004 for (auto& filter : trace_message_filters_)
(...skipping 19 matching lines...) Expand all
984 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse, 1024 base::Bind(&TracingControllerImpl::OnProcessMemoryDumpResponse,
985 base::Unretained(this), 1025 base::Unretained(this),
986 base::RetainedRef(trace_message_filter), dump_guid, 1026 base::RetainedRef(trace_message_filter), dump_guid,
987 success)); 1027 success));
988 return; 1028 return;
989 } 1029 }
990 1030
991 TraceMessageFilterSet::iterator it = 1031 TraceMessageFilterSet::iterator it =
992 pending_memory_dump_filters_.find(trace_message_filter); 1032 pending_memory_dump_filters_.find(trace_message_filter);
993 1033
994 if (pending_memory_dump_guid_ != dump_guid || 1034 DCHECK(!queued_memory_dump_requests_.empty());
1035 if (queued_memory_dump_requests_.front().args.dump_guid != dump_guid ||
995 it == pending_memory_dump_filters_.end()) { 1036 it == pending_memory_dump_filters_.end()) {
996 DLOG(WARNING) << "Received unexpected memory dump response: " << dump_guid; 1037 DLOG(WARNING) << "Received unexpected memory dump response: " << dump_guid;
997 return; 1038 return;
998 } 1039 }
999 1040
1000 DCHECK_GT(pending_memory_dump_ack_count_, 0); 1041 DCHECK_GT(pending_memory_dump_ack_count_, 0);
1001 --pending_memory_dump_ack_count_; 1042 --pending_memory_dump_ack_count_;
1002 pending_memory_dump_filters_.erase(it); 1043 pending_memory_dump_filters_.erase(it);
1003 if (!success) { 1044 if (!success) {
1004 ++failed_memory_dump_count_; 1045 ++failed_memory_dump_count_;
(...skipping 13 matching lines...) Expand all
1018 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix 1059 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
1019 << " aborted on the current process"; 1060 << " aborted on the current process";
1020 } 1061 }
1021 FinalizeGlobalMemoryDumpIfAllProcessesReplied(); 1062 FinalizeGlobalMemoryDumpIfAllProcessesReplied();
1022 } 1063 }
1023 1064
1024 void TracingControllerImpl::FinalizeGlobalMemoryDumpIfAllProcessesReplied() { 1065 void TracingControllerImpl::FinalizeGlobalMemoryDumpIfAllProcessesReplied() {
1025 if (pending_memory_dump_ack_count_ > 0) 1066 if (pending_memory_dump_ack_count_ > 0)
1026 return; 1067 return;
1027 1068
1028 DCHECK_NE(0u, pending_memory_dump_guid_); 1069 DCHECK(!queued_memory_dump_requests_.empty());
1029 const bool global_success = failed_memory_dump_count_ == 0; 1070 {
Primiano Tucci (use gerrit) 2016/06/23 11:09:16 why this extra scope, seems unnecessary?
petrcermak 2016/06/24 10:49:57 It's because |callback| is a reference to the fron
Primiano Tucci (use gerrit) 2016/06/24 11:23:05 ahh right. smart.
1030 if (!pending_memory_dump_callback_.is_null()) { 1071 const auto& callback = queued_memory_dump_requests_.front().callback;
1031 pending_memory_dump_callback_.Run(pending_memory_dump_guid_, 1072 if (!callback.is_null()) {
1032 global_success); 1073 const bool global_success = failed_memory_dump_count_ == 0;
1033 pending_memory_dump_callback_.Reset(); 1074 callback.Run(queued_memory_dump_requests_.front().args.dump_guid,
1075 global_success);
1076 }
1034 } 1077 }
1035 pending_memory_dump_guid_ = 0; 1078 queued_memory_dump_requests_.pop_front();
1079
1080 // Schedule the next queued dump (if applicable).
1081 if (!queued_memory_dump_requests_.empty()) {
1082 BrowserThread::PostTask(
1083 BrowserThread::UI, FROM_HERE,
1084 base::Bind(&TracingControllerImpl::PerformGlobalMemoryDump,
1085 base::Unretained(this)));
1086 }
1036 } 1087 }
1037 1088
1038 } // namespace content 1089 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698