| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |