blob: 51c266a707723430a3aad94f3d1531b4ebc9c017 [file] [log] [blame]
[email protected]02798a982012-01-27 00:45:331// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d27893f62010-07-03 05:47:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4c01d4992012-01-23 23:33:015#include "content/browser/browser_child_process_host_impl.h"
[email protected]d27893f62010-07-03 05:47:426
[email protected]2b065f82012-10-18 07:11:167#include "base/base_switches.h"
[email protected]4306c3792011-12-02 01:57:538#include "base/bind.h"
[email protected]d27893f62010-07-03 05:47:429#include "base/command_line.h"
Yuzhu Shen32fcad72017-09-14 23:12:3710#include "base/debug/crash_logging.h"
wfhaf32d0b2015-04-07 02:21:3611#include "base/debug/dump_without_crashing.h"
erikchen55edbff2016-05-03 23:53:1712#include "base/feature_list.h"
[email protected]57999812013-02-24 05:40:5213#include "base/files/file_path.h"
[email protected]d3c6c0d72010-12-09 08:15:0414#include "base/lazy_instance.h"
[email protected]d27893f62010-07-03 05:47:4215#include "base/logging.h"
avib7348942015-12-25 20:57:1016#include "base/macros.h"
erikchen55edbff2016-05-03 23:53:1717#include "base/metrics/field_trial.h"
Ilya Sherman1c811db2017-12-14 10:36:1818#include "base/metrics/histogram_functions.h"
asvitkine30330812016-08-30 04:01:0819#include "base/metrics/histogram_macros.h"
bcwhiteb58a5fe2016-08-22 16:25:5620#include "base/metrics/persistent_histogram_allocator.h"
21#include "base/metrics/persistent_memory_allocator.h"
[email protected]7286e3fc2011-07-19 22:13:2422#include "base/stl_util.h"
[email protected]10994d132013-06-11 07:16:1823#include "base/strings/string_util.h"
rockotda9887902016-08-19 20:46:4224#include "base/strings/stringprintf.h"
[email protected]162a9fd2013-03-06 20:47:4925#include "base/synchronization/waitable_event.h"
Eric Seckler8652dcd52018-09-20 10:42:2826#include "base/task/post_task.h"
rockot229fb28e2016-06-16 04:46:1627#include "base/threading/thread_task_runner_handle.h"
Ken Rockot315def72018-11-10 02:16:1028#include "base/token.h"
avib7348942015-12-25 20:57:1029#include "build/build_config.h"
Ehsan Chiniforooshandef633e02018-04-24 02:05:0230#include "components/tracing/common/trace_startup_config.h"
primianoccb26c62016-06-01 21:50:0231#include "components/tracing/common/tracing_switches.h"
Robert Sesek1419427e2017-12-07 15:01:3232#include "content/browser/bad_message.h"
Ehsan Chiniforooshanf192e8a22018-03-27 03:18:2033#include "content/browser/browser_main_loop.h"
Nicholas Verne91bf4a632017-10-12 21:14:2434#include "content/browser/histogram_controller.h"
[email protected]678c0362012-12-05 08:02:4435#include "content/browser/loader/resource_message_filter.h"
benff461632016-10-06 14:27:3336#include "content/browser/service_manager/service_manager_context.h"
[email protected]3a85b1f2013-02-01 04:47:4037#include "content/browser/tracing/trace_message_filter.h"
[email protected]4734d0b2011-12-03 07:10:4438#include "content/common/child_process_host_impl.h"
bend32292b2016-10-07 00:21:5839#include "content/common/service_manager/child_connection.h"
[email protected]4967f792012-01-20 22:14:4040#include "content/public/browser/browser_child_process_host_delegate.h"
[email protected]f4eaf7b92013-02-28 22:00:4041#include "content/public/browser/browser_child_process_observer.h"
Eric Seckler8652dcd52018-09-20 10:42:2842#include "content/public/browser/browser_task_traits.h"
[email protected]57999812013-02-24 05:40:5243#include "content/public/browser/browser_thread.h"
[email protected]4306c3792011-12-02 01:57:5344#include "content/public/browser/child_process_data.h"
[email protected]87f3c082011-10-19 18:07:4445#include "content/public/browser/content_browser_client.h"
ke.he19b5e6a2016-10-27 08:47:0946#include "content/public/common/connection_filter.h"
lawrencewu2c930822016-10-13 13:54:2547#include "content/public/common/content_features.h"
[email protected]c08950d22011-10-13 22:20:2948#include "content/public/common/content_switches.h"
[email protected]f3b357692013-03-22 05:16:1349#include "content/public/common/process_type.h"
[email protected]b39ef1cb2011-10-25 04:46:5550#include "content/public/common/result_codes.h"
jcivelli828cd7f2017-01-18 19:50:4651#include "content/public/common/sandboxed_process_launcher_delegate.h"
ke.he19b5e6a2016-10-27 08:47:0952#include "content/public/common/service_manager_connection.h"
Nicholas Verne91bf4a632017-10-12 21:14:2453#include "mojo/public/cpp/system/platform_handle.h"
Yoichi Osato14073bd2019-06-04 11:06:3754#include "net/websockets/websocket_basic_stream.h"
ochang6a8400e2017-05-01 21:28:2455#include "services/service_manager/embedder/switches.h"
Ken Rockota86fa542018-11-13 21:47:1356#include "services/service_manager/public/cpp/constants.h"
[email protected]d27893f62010-07-03 05:47:4257
[email protected]f1675202012-07-09 15:18:0058#if defined(OS_MACOSX)
[email protected]458433c2012-02-29 23:43:3959#include "content/browser/mach_broker_mac.h"
[email protected]3838ca12011-11-02 14:37:1560#endif
[email protected]a3a7e2c2011-09-16 23:07:0561
[email protected]130757672012-10-24 00:26:1962namespace content {
[email protected]d27893f62010-07-03 05:47:4263namespace {
64
scottmg5e65e3a2017-03-08 08:48:4665static base::LazyInstance<
66 BrowserChildProcessHostImpl::BrowserChildProcessList>::DestructorAtExit
[email protected]4967f792012-01-20 22:14:4067 g_child_process_list = LAZY_INSTANCE_INITIALIZER;
[email protected]d27893f62010-07-03 05:47:4268
Trent Apteda250ec3ab2018-08-19 08:52:1969base::LazyInstance<base::ObserverList<BrowserChildProcessObserver>::Unchecked>::
Daniel Bratellbfcfe222017-10-17 17:57:0070 DestructorAtExit g_browser_child_process_observers =
71 LAZY_INSTANCE_INITIALIZER;
[email protected]f4eaf7b92013-02-28 22:00:4072
afakhry9cc79002015-10-22 19:25:1573void NotifyProcessLaunchedAndConnected(const ChildProcessData& data) {
Daniel Bratellbfcfe222017-10-17 17:57:0074 for (auto& observer : g_browser_child_process_observers.Get())
ericwilligers254597b2016-10-17 10:32:3175 observer.BrowserChildProcessLaunchedAndConnected(data);
afakhry9cc79002015-10-22 19:25:1576}
77
[email protected]f4eaf7b92013-02-28 22:00:4078void NotifyProcessHostConnected(const ChildProcessData& data) {
Daniel Bratellbfcfe222017-10-17 17:57:0079 for (auto& observer : g_browser_child_process_observers.Get())
ericwilligers254597b2016-10-17 10:32:3180 observer.BrowserChildProcessHostConnected(data);
[email protected]f4eaf7b92013-02-28 22:00:4081}
82
83void NotifyProcessHostDisconnected(const ChildProcessData& data) {
Daniel Bratellbfcfe222017-10-17 17:57:0084 for (auto& observer : g_browser_child_process_observers.Get())
ericwilligers254597b2016-10-17 10:32:3185 observer.BrowserChildProcessHostDisconnected(data);
[email protected]f4eaf7b92013-02-28 22:00:4086}
87
Bo Liue9624612018-04-28 00:39:0888#if !defined(OS_ANDROID)
Bo Liu2a489402018-04-24 23:41:2789void NotifyProcessCrashed(const ChildProcessData& data,
90 const ChildProcessTerminationInfo& info) {
Daniel Bratellbfcfe222017-10-17 17:57:0091 for (auto& observer : g_browser_child_process_observers.Get())
Bo Liu2a489402018-04-24 23:41:2792 observer.BrowserChildProcessCrashed(data, info);
[email protected]4306c3792011-12-02 01:57:5393}
Bo Liue9624612018-04-28 00:39:0894#endif
[email protected]d27893f62010-07-03 05:47:4295
Bo Liu2a489402018-04-24 23:41:2796void NotifyProcessKilled(const ChildProcessData& data,
97 const ChildProcessTerminationInfo& info) {
Daniel Bratellbfcfe222017-10-17 17:57:0098 for (auto& observer : g_browser_child_process_observers.Get())
Bo Liu2a489402018-04-24 23:41:2799 observer.BrowserChildProcessKilled(data, info);
wfhf0003292015-08-18 22:16:46100}
101
[email protected]d27893f62010-07-03 05:47:42102} // namespace
103
[email protected]4967f792012-01-20 22:14:40104BrowserChildProcessHost* BrowserChildProcessHost::Create(
vadimt379d7fe2015-04-01 00:09:35105 content::ProcessType process_type,
[email protected]4967f792012-01-20 22:14:40106 BrowserChildProcessHostDelegate* delegate) {
rockotda9887902016-08-19 20:46:42107 return Create(process_type, delegate, std::string());
amistry6ad1e812016-06-06 05:36:30108}
109
110BrowserChildProcessHost* BrowserChildProcessHost::Create(
111 content::ProcessType process_type,
112 BrowserChildProcessHostDelegate* delegate,
rockotda9887902016-08-19 20:46:42113 const std::string& service_name) {
114 return new BrowserChildProcessHostImpl(process_type, delegate, service_name);
[email protected]4967f792012-01-20 22:14:40115}
116
amistryfaa231a42015-05-20 01:49:12117BrowserChildProcessHost* BrowserChildProcessHost::FromID(int child_process_id) {
118 DCHECK_CURRENTLY_ON(BrowserThread::IO);
119 BrowserChildProcessHostImpl::BrowserChildProcessList* process_list =
120 g_child_process_list.Pointer();
121 for (BrowserChildProcessHostImpl* host : *process_list) {
122 if (host->GetData().id == child_process_id)
123 return host;
124 }
125 return nullptr;
126}
127
[email protected]458433c2012-02-29 23:43:39128#if defined(OS_MACOSX)
erikchencd3e0e7b2015-10-01 22:53:51129base::PortProvider* BrowserChildProcessHost::GetPortProvider() {
[email protected]458433c2012-02-29 23:43:39130 return MachBroker::GetInstance();
131}
132#endif
133
[email protected]f4eaf7b92013-02-28 22:00:40134// static
[email protected]4c01d4992012-01-23 23:33:01135BrowserChildProcessHostImpl::BrowserChildProcessList*
Maggie Chen47b8dc1d2018-11-10 00:12:34136BrowserChildProcessHostImpl::GetIterator() {
[email protected]4967f792012-01-20 22:14:40137 return g_child_process_list.Pointer();
138}
139
[email protected]f4eaf7b92013-02-28 22:00:40140// static
141void BrowserChildProcessHostImpl::AddObserver(
142 BrowserChildProcessObserver* observer) {
mostynbfbcdc27a2015-03-13 17:58:52143 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Daniel Bratellbfcfe222017-10-17 17:57:00144 g_browser_child_process_observers.Get().AddObserver(observer);
[email protected]f4eaf7b92013-02-28 22:00:40145}
146
147// static
148void BrowserChildProcessHostImpl::RemoveObserver(
149 BrowserChildProcessObserver* observer) {
150 // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126.
Daniel Bratellbfcfe222017-10-17 17:57:00151 g_browser_child_process_observers.Get().RemoveObserver(observer);
[email protected]f4eaf7b92013-02-28 22:00:40152}
153
[email protected]4c01d4992012-01-23 23:33:01154BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
vadimt379d7fe2015-04-01 00:09:35155 content::ProcessType process_type,
amistry6ad1e812016-06-06 05:36:30156 BrowserChildProcessHostDelegate* delegate,
rockotda9887902016-08-19 20:46:42157 const std::string& service_name)
[email protected]f3b357692013-03-22 05:16:13158 : data_(process_type),
[email protected]9dd90152013-08-02 22:09:13159 delegate_(delegate),
sadrul6c5aed8c2017-01-11 23:11:44160 channel_(nullptr),
amistry012289f2016-04-01 00:56:37161 is_channel_connected_(false),
rockot229fb28e2016-06-16 04:46:16162 notify_child_disconnected_(false),
163 weak_factory_(this) {
[email protected]4734d0b2011-12-03 07:10:44164 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
[email protected]4306c3792011-12-02 01:57:53165
Ayu Ishii75cc1062019-01-08 01:27:37166 child_process_host_ = ChildProcessHost::Create(this);
ssid72c5d6822015-06-26 15:51:42167 AddFilter(new TraceMessageFilter(data_.id));
[email protected]38917fe2011-04-06 17:29:12168
169 g_child_process_list.Get().push_back(this);
[email protected]130757672012-10-24 00:26:19170 GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
[email protected]30c4c67a2014-07-22 02:33:55171
rockotda9887902016-08-19 20:46:42172 if (!service_name.empty()) {
173 DCHECK_CURRENTLY_ON(BrowserThread::IO);
Ken Rockota86fa542018-11-13 21:47:13174 child_connection_ = std::make_unique<ChildConnection>(
175 service_manager::Identity(
176 service_name, service_manager::kSystemInstanceGroup,
177 base::Token::CreateRandom(), base::Token::CreateRandom()),
178 &mojo_invitation_, ServiceManagerContext::GetConnectorForIOThread(),
179 base::ThreadTaskRunnerHandle::Get());
Will Harrisedb011f2018-06-01 20:28:44180 data_.metrics_name = service_name;
rockotda9887902016-08-19 20:46:42181 }
bcwhiteb58a5fe2016-08-22 16:25:56182
183 // Create a persistent memory segment for subprocess histograms.
184 CreateMetricsAllocator();
[email protected]38917fe2011-04-06 17:29:12185}
186
[email protected]4c01d4992012-01-23 23:33:01187BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() {
[email protected]d3c6c0d72010-12-09 08:15:04188 g_child_process_list.Get().remove(this);
amistry012289f2016-04-01 00:56:37189
190 if (notify_child_disconnected_) {
Eric Seckler8652dcd52018-09-20 10:42:28191 base::PostTaskWithTraits(
192 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26193 base::BindOnce(&NotifyProcessHostDisconnected, data_.Duplicate()));
amistry012289f2016-04-01 00:56:37194 }
[email protected]d27893f62010-07-03 05:47:42195}
196
197// static
[email protected]4c01d4992012-01-23 23:33:01198void BrowserChildProcessHostImpl::TerminateAll() {
mostynbfbcdc27a2015-03-13 17:58:52199 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]f174efd2012-01-17 18:43:33200 // Make a copy since the BrowserChildProcessHost dtor mutates the original
201 // list.
202 BrowserChildProcessList copy = g_child_process_list.Get();
jdoerrie55ec69d2018-10-08 13:34:46203 for (auto it = copy.begin(); it != copy.end(); ++it) {
[email protected]5998d9d2012-03-06 04:25:26204 delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl.
205 }
[email protected]d27893f62010-07-03 05:47:42206}
207
erikchen55edbff2016-05-03 23:53:17208// static
lawrencewu0b4964922016-10-25 16:28:14209void BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(
erikchen55edbff2016-05-03 23:53:17210 base::CommandLine* cmd_line) {
erikchen55edbff2016-05-03 23:53:17211 // If we run base::FieldTrials, we want to pass to their state to the
212 // child process so that it can act in accordance with each state.
lawrencewu5e03cd32016-12-05 16:23:28213 base::FieldTrialList::CopyFieldTrialStateToFlags(
214 switches::kFieldTrialHandle, switches::kEnableFeatures,
215 switches::kDisableFeatures, cmd_line);
erikchen55edbff2016-05-03 23:53:17216}
217
Ehsan Chiniforooshanf192e8a22018-03-27 03:18:20218// static
219void BrowserChildProcessHostImpl::CopyTraceStartupFlags(
220 base::CommandLine* cmd_line) {
Ehsan Chiniforooshandef633e02018-04-24 02:05:02221 if (tracing::TraceStartupConfig::GetInstance()->IsEnabled()) {
Ehsan Chiniforooshanf192e8a22018-03-27 03:18:20222 const auto trace_config =
Ehsan Chiniforooshandef633e02018-04-24 02:05:02223 tracing::TraceStartupConfig::GetInstance()->GetTraceConfig();
Ehsan Chiniforooshanf192e8a22018-03-27 03:18:20224 if (!trace_config.IsArgumentFilterEnabled()) {
225 // The only trace option that we can pass through switches is the record
226 // mode. Other trace options should have the default value.
227 //
228 // TODO(chiniforooshan): Add other trace options to switches if, for
229 // example, they are used in a telemetry test that needs startup trace
230 // events from renderer processes.
231 cmd_line->AppendSwitchASCII(switches::kTraceStartup,
232 trace_config.ToCategoryFilterString());
233 cmd_line->AppendSwitchASCII(
234 switches::kTraceStartupRecordMode,
235 base::trace_event::TraceConfig::TraceRecordModeToStr(
236 trace_config.GetTraceRecordMode()));
237 }
238 }
239}
240
[email protected]4c01d4992012-01-23 23:33:01241void BrowserChildProcessHostImpl::Launch(
jcivellid20cc0b2016-12-22 03:51:41242 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
243 std::unique_ptr<base::CommandLine> cmd_line,
sievers954e37a2015-03-28 01:50:24244 bool terminate_on_shutdown) {
jcivellid20cc0b2016-12-22 03:51:41245 GetContentClient()->browser()->AppendExtraCommandLineSwitches(cmd_line.get(),
246 data_.id);
Maggie Chen47b8dc1d2018-11-10 00:12:34247 LaunchWithoutExtraCommandLineSwitches(
248 std::move(delegate), std::move(cmd_line), terminate_on_shutdown);
[email protected]d27893f62010-07-03 05:47:42249}
250
Lucas Furukawa Gadani0d5e7142019-04-18 23:00:50251const ChildProcessData& BrowserChildProcessHostImpl::GetData() {
mostynbfbcdc27a2015-03-13 17:58:52252 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]4967f792012-01-20 22:14:40253 return data_;
254}
255
Lucas Furukawa Gadani0d5e7142019-04-18 23:00:50256ChildProcessHost* BrowserChildProcessHostImpl::GetHost() {
mostynbfbcdc27a2015-03-13 17:58:52257 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]4967f792012-01-20 22:14:40258 return child_process_host_.get();
259}
260
Lucas Furukawa Gadani0d5e7142019-04-18 23:00:50261const base::Process& BrowserChildProcessHostImpl::GetProcess() {
mostynbfbcdc27a2015-03-13 17:58:52262 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]5d84d012010-12-02 17:17:21263 DCHECK(child_process_.get())
264 << "Requesting a child process handle before launching.";
rvargas079d1842014-10-17 22:32:16265 DCHECK(child_process_->GetProcess().IsValid())
[email protected]5d84d012010-12-02 17:17:21266 << "Requesting a child process handle before launch has completed OK.";
rvargas5779b382014-11-18 20:44:11267 return child_process_->GetProcess();
[email protected]5d84d012010-12-02 17:17:21268}
269
Alex Ilin30e7d062019-02-21 12:24:53270std::unique_ptr<base::PersistentMemoryAllocator>
bcwhiteb58a5fe2016-08-22 16:25:56271BrowserChildProcessHostImpl::TakeMetricsAllocator() {
272 return std::move(metrics_allocator_);
273}
274
[email protected]fcf75d42013-12-03 20:11:26275void BrowserChildProcessHostImpl::SetName(const base::string16& name) {
mostynbfbcdc27a2015-03-13 17:58:52276 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]f174efd2012-01-17 18:43:33277 data_.name = name;
278}
279
Will Harrisedb011f2018-06-01 20:28:44280void BrowserChildProcessHostImpl::SetMetricsName(
281 const std::string& metrics_name) {
282 DCHECK_CURRENTLY_ON(BrowserThread::IO);
283 data_.metrics_name = metrics_name;
284}
285
Francois Doray884da022018-10-30 23:45:58286void BrowserChildProcessHostImpl::SetProcess(base::Process process) {
mostynbfbcdc27a2015-03-13 17:58:52287 DCHECK_CURRENTLY_ON(BrowserThread::IO);
Francois Doray884da022018-10-30 23:45:58288 data_.SetProcess(std::move(process));
[email protected]f174efd2012-01-17 18:43:33289}
290
Ken Rockotea1716a02017-05-11 05:49:10291service_manager::mojom::ServiceRequest
292BrowserChildProcessHostImpl::TakeInProcessServiceRequest() {
Ken Rockot026afc32018-06-04 19:19:18293 auto invitation = std::move(mojo_invitation_);
Ken Rockotf4d8a942017-05-13 00:10:37294 return service_manager::mojom::ServiceRequest(
Ken Rockot026afc32018-06-04 19:19:18295 invitation.ExtractMessagePipe(child_connection_->service_token()));
sammc2b0375b2016-12-22 01:26:17296}
297
[email protected]4c01d4992012-01-23 23:33:01298void BrowserChildProcessHostImpl::ForceShutdown() {
mostynbfbcdc27a2015-03-13 17:58:52299 DCHECK_CURRENTLY_ON(BrowserThread::IO);
[email protected]d3c6c0d72010-12-09 08:15:04300 g_child_process_list.Get().remove(this);
[email protected]4cb43102011-12-02 20:24:49301 child_process_host_->ForceShutdown();
[email protected]d27893f62010-07-03 05:47:42302}
303
[email protected]ba780c12013-10-01 17:07:06304void BrowserChildProcessHostImpl::AddFilter(BrowserMessageFilter* filter) {
305 child_process_host_->AddFilter(filter->GetFilter());
306}
307
Maggie Chen47b8dc1d2018-11-10 00:12:34308void BrowserChildProcessHostImpl::LaunchWithoutExtraCommandLineSwitches(
309 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
310 std::unique_ptr<base::CommandLine> cmd_line,
311 bool terminate_on_shutdown) {
312 DCHECK_CURRENTLY_ON(BrowserThread::IO);
313 const base::CommandLine& browser_command_line =
314 *base::CommandLine::ForCurrentProcess();
315 static const char* const kForwardSwitches[] = {
Yoichi Osato14073bd2019-06-04 11:06:37316 net::kWebSocketReadBufferSize,
Maggie Chen47b8dc1d2018-11-10 00:12:34317 service_manager::switches::kDisableInProcessStackTraces,
Yue Ru Suna50a80f2019-02-08 05:02:58318 switches::kDisableBestEffortTasks,
Maggie Chen47b8dc1d2018-11-10 00:12:34319 switches::kDisableLogging,
Oystein Eftevaag001c99172019-03-23 00:37:29320 switches::kDisablePerfetto,
Maggie Chen47b8dc1d2018-11-10 00:12:34321 switches::kEnableLogging,
Maggie Chen47b8dc1d2018-11-10 00:12:34322 switches::kIPCConnectionTimeout,
Greg Thompson54915832018-12-21 17:11:47323 switches::kLogFile,
Maggie Chen47b8dc1d2018-11-10 00:12:34324 switches::kLoggingLevel,
325 switches::kTraceToConsole,
326 switches::kV,
327 switches::kVModule,
328 };
329 cmd_line->CopySwitchesFrom(browser_command_line, kForwardSwitches,
330 base::size(kForwardSwitches));
331
332 if (child_connection_) {
333 cmd_line->AppendSwitchASCII(
334 service_manager::switches::kServiceRequestChannelToken,
335 child_connection_->service_token());
336 }
337
338 // All processes should have a non-empty metrics name.
339 DCHECK(!data_.metrics_name.empty());
340
341 notify_child_disconnected_ = true;
342 child_process_.reset(new ChildProcessLauncher(
343 std::move(delegate), std::move(cmd_line), data_.id, this,
344 std::move(mojo_invitation_),
345 base::BindRepeating(&BrowserChildProcessHostImpl::OnMojoError,
346 weak_factory_.GetWeakPtr(),
347 base::ThreadTaskRunnerHandle::Get()),
348 terminate_on_shutdown));
349 ShareMetricsAllocatorToProcess();
350}
351
bena06f7d62017-04-04 20:48:52352void BrowserChildProcessHostImpl::BindInterface(
353 const std::string& interface_name,
354 mojo::ScopedMessagePipeHandle interface_pipe) {
rockotda9887902016-08-19 20:46:42355 DCHECK_CURRENTLY_ON(BrowserThread::IO);
356 if (!child_connection_)
bena06f7d62017-04-04 20:48:52357 return;
rockotda9887902016-08-19 20:46:42358
bena06f7d62017-04-04 20:48:52359 child_connection_->BindInterface(interface_name, std::move(interface_pipe));
rockotda9887902016-08-19 20:46:42360}
361
[email protected]ef2f6ba2014-05-15 23:06:07362void BrowserChildProcessHostImpl::HistogramBadMessageTerminated(
Wei-Yin Chen (陳威尹)223326c2017-07-21 02:08:28363 ProcessType process_type) {
[email protected]ef2f6ba2014-05-15 23:06:07364 UMA_HISTOGRAM_ENUMERATION("ChildProcess.BadMessgeTerminated", process_type,
365 PROCESS_TYPE_MAX);
366}
367
Min Qineb961902019-03-16 08:08:22368#if defined(OS_ANDROID)
369void BrowserChildProcessHostImpl::EnableWarmUpConnection() {
370 can_use_warm_up_connection_ = true;
371}
372#endif
373
Bo Liu0d2a2322018-04-19 00:18:09374ChildProcessTerminationInfo BrowserChildProcessHostImpl::GetTerminationInfo(
375 bool known_dead) {
mostynbfbcdc27a2015-03-13 17:58:52376 DCHECK_CURRENTLY_ON(BrowserThread::IO);
Bo Liu0d2a2322018-04-19 00:18:09377 if (!child_process_) {
378 // If the delegate doesn't use Launch() helper.
379 ChildProcessTerminationInfo info;
Francois Doray884da022018-10-30 23:45:58380 info.status = base::GetTerminationStatus(data_.GetProcess().Handle(),
381 &info.exit_code);
Bo Liu0d2a2322018-04-19 00:18:09382 return info;
383 }
384 return child_process_->GetChildTerminationInfo(known_dead);
[email protected]d27893f62010-07-03 05:47:42385}
386
[email protected]4c01d4992012-01-23 23:33:01387bool BrowserChildProcessHostImpl::OnMessageReceived(
388 const IPC::Message& message) {
[email protected]4967f792012-01-20 22:14:40389 return delegate_->OnMessageReceived(message);
[email protected]4cb43102011-12-02 20:24:49390}
391
avib7348942015-12-25 20:57:10392void BrowserChildProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
afakhry9cc79002015-10-22 19:25:15393 DCHECK_CURRENTLY_ON(BrowserThread::IO);
394
395 is_channel_connected_ = true;
amistry012289f2016-04-01 00:56:37396 notify_child_disconnected_ = true;
afakhry9cc79002015-10-22 19:25:15397
[email protected]162a9fd2013-03-06 20:47:49398#if defined(OS_WIN)
399 // From this point onward, the exit of the child process is detected by an
400 // error on the IPC channel.
[email protected]162a9fd2013-03-06 20:47:49401 early_exit_watcher_.StopWatching();
402#endif
403
Eric Seckler8652dcd52018-09-20 10:42:28404 base::PostTaskWithTraits(
405 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26406 base::BindOnce(&NotifyProcessHostConnected, data_.Duplicate()));
[email protected]162a9fd2013-03-06 20:47:49407
[email protected]4967f792012-01-20 22:14:40408 delegate_->OnChannelConnected(peer_pid);
afakhry9cc79002015-10-22 19:25:15409
410 if (IsProcessLaunched()) {
Eric Seckler8652dcd52018-09-20 10:42:28411 base::PostTaskWithTraits(
412 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26413 base::BindOnce(&NotifyProcessLaunchedAndConnected, data_.Duplicate()));
afakhry9cc79002015-10-22 19:25:15414 }
[email protected]4967f792012-01-20 22:14:40415}
416
[email protected]4c01d4992012-01-23 23:33:01417void BrowserChildProcessHostImpl::OnChannelError() {
[email protected]4967f792012-01-20 22:14:40418 delegate_->OnChannelError();
[email protected]0d6e9bd2011-10-18 04:29:16419}
420
[email protected]ef2f6ba2014-05-15 23:06:07421void BrowserChildProcessHostImpl::OnBadMessageReceived(
422 const IPC::Message& message) {
Roman Karaseva43d5b4e2017-12-21 03:06:02423 std::string log_message = "Bad message received of type: ";
424 if (message.IsValid()) {
425 log_message += std::to_string(message.type());
426 } else {
427 log_message += "unknown";
428 }
sadrul73f39a62017-01-11 04:07:24429 TerminateOnBadMessageReceived(log_message);
jbauman278b2cc2016-01-08 22:48:53430}
431
sadrul73f39a62017-01-11 04:07:24432void BrowserChildProcessHostImpl::TerminateOnBadMessageReceived(
433 const std::string& error) {
Wei-Yin Chen (陳威尹)223326c2017-07-21 02:08:28434 HistogramBadMessageTerminated(static_cast<ProcessType>(data_.process_type));
avi83883c82014-12-23 00:08:49435 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]e44d1342014-05-16 21:29:33436 switches::kDisableKillAfterBadIPC)) {
437 return;
438 }
sadrul73f39a62017-01-11 04:07:24439 LOG(ERROR) << "Terminating child process for bad IPC message: " << error;
wfhaf32d0b2015-04-07 02:21:36440 // Create a memory dump. This will contain enough stack frames to work out
441 // what the bad message was.
442 base::debug::DumpWithoutCrashing();
443
Bo Liue06143912018-04-20 20:42:30444 child_process_->Terminate(RESULT_CODE_KILLED_BAD_MESSAGE);
[email protected]ef2f6ba2014-05-15 23:06:07445}
446
sadrul6c5aed8c2017-01-11 23:11:44447void BrowserChildProcessHostImpl::OnChannelInitialized(IPC::Channel* channel) {
448 channel_ = channel;
449}
450
[email protected]4c01d4992012-01-23 23:33:01451void BrowserChildProcessHostImpl::OnChildDisconnected() {
mostynbfbcdc27a2015-03-13 17:58:52452 DCHECK_CURRENTLY_ON(BrowserThread::IO);
jbauman319402e2014-10-21 17:52:21453#if defined(OS_WIN)
454 // OnChildDisconnected may be called without OnChannelConnected, so stop the
455 // early exit watcher so GetTerminationStatus can close the process handle.
456 early_exit_watcher_.StopWatching();
457#endif
Francois Doray884da022018-10-30 23:45:58458 if (child_process_.get() || data_.GetProcess().IsValid()) {
Bo Liu0d2a2322018-04-19 00:18:09459 ChildProcessTerminationInfo info =
460 GetTerminationInfo(true /* known_dead */);
Bo Liue9624612018-04-28 00:39:08461#if defined(OS_ANDROID)
462 delegate_->OnProcessCrashed(info.exit_code);
Eric Seckler8652dcd52018-09-20 10:42:28463 base::PostTaskWithTraits(
464 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26465 base::BindOnce(&NotifyProcessKilled, data_.Duplicate(), info));
Bo Liue9624612018-04-28 00:39:08466#else // OS_ANDROID
Bo Liu0d2a2322018-04-19 00:18:09467 switch (info.status) {
[email protected]6d057a0c2013-07-09 21:12:07468 case base::TERMINATION_STATUS_PROCESS_CRASHED:
469 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: {
Bo Liu0d2a2322018-04-19 00:18:09470 delegate_->OnProcessCrashed(info.exit_code);
Eric Seckler8652dcd52018-09-20 10:42:28471 base::PostTaskWithTraits(
472 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26473 base::BindOnce(&NotifyProcessCrashed, data_.Duplicate(), info));
[email protected]6d057a0c2013-07-09 21:12:07474 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed2",
Wei-Yin Chen (陳威尹)3330991f2017-07-27 17:25:57475 static_cast<ProcessType>(data_.process_type),
[email protected]6d057a0c2013-07-09 21:12:07476 PROCESS_TYPE_MAX);
477 break;
478 }
oshima620225722015-06-04 19:45:27479#if defined(OS_CHROMEOS)
480 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
481#endif
[email protected]6d057a0c2013-07-09 21:12:07482 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: {
Bo Liu0d2a2322018-04-19 00:18:09483 delegate_->OnProcessCrashed(info.exit_code);
Eric Seckler8652dcd52018-09-20 10:42:28484 base::PostTaskWithTraits(
485 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26486 base::BindOnce(&NotifyProcessKilled, data_.Duplicate(), info));
[email protected]6d057a0c2013-07-09 21:12:07487 // Report that this child process was killed.
488 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2",
Wei-Yin Chen (陳威尹)3330991f2017-07-27 17:25:57489 static_cast<ProcessType>(data_.process_type),
[email protected]6d057a0c2013-07-09 21:12:07490 PROCESS_TYPE_MAX);
491 break;
492 }
493 case base::TERMINATION_STATUS_STILL_RUNNING: {
494 UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive2",
Wei-Yin Chen (陳威尹)3330991f2017-07-27 17:25:57495 static_cast<ProcessType>(data_.process_type),
[email protected]6d057a0c2013-07-09 21:12:07496 PROCESS_TYPE_MAX);
Nico Weber9dbefa62018-01-27 01:01:42497 break;
[email protected]6d057a0c2013-07-09 21:12:07498 }
499 default:
500 break;
[email protected]12fed812011-09-16 05:47:29501 }
Bo Liue9624612018-04-28 00:39:08502#endif // OS_ANDROID
[email protected]6d057a0c2013-07-09 21:12:07503 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected2",
Wei-Yin Chen (陳威尹)3330991f2017-07-27 17:25:57504 static_cast<ProcessType>(data_.process_type),
[email protected]6d057a0c2013-07-09 21:12:07505 PROCESS_TYPE_MAX);
oshima620225722015-06-04 19:45:27506#if defined(OS_CHROMEOS)
Bo Liu0d2a2322018-04-19 00:18:09507 if (info.status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM) {
oshima620225722015-06-04 19:45:27508 UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2.OOM",
Wei-Yin Chen (陳威尹)3330991f2017-07-27 17:25:57509 static_cast<ProcessType>(data_.process_type),
oshima620225722015-06-04 19:45:27510 PROCESS_TYPE_MAX);
511 }
512#endif
[email protected]d27893f62010-07-03 05:47:42513 }
sadrul6c5aed8c2017-01-11 23:11:44514 channel_ = nullptr;
[email protected]4967f792012-01-20 22:14:40515 delete delegate_; // Will delete us
[email protected]a3a7e2c2011-09-16 23:07:05516}
517
[email protected]4c01d4992012-01-23 23:33:01518bool BrowserChildProcessHostImpl::Send(IPC::Message* message) {
[email protected]4cb43102011-12-02 20:24:49519 return child_process_host_->Send(message);
520}
521
bcwhiteb58a5fe2016-08-22 16:25:56522void BrowserChildProcessHostImpl::CreateMetricsAllocator() {
523 // Create a persistent memory segment for subprocess histograms only if
524 // they're active in the browser.
525 // TODO(bcwhite): Remove this once persistence is always enabled.
526 if (!base::GlobalHistogramAllocator::Get())
527 return;
528
529 // Determine the correct parameters based on the process type.
530 size_t memory_size;
531 base::StringPiece metrics_name;
532 switch (data_.process_type) {
bcwhite2496c83e2016-08-29 17:29:25533 case PROCESS_TYPE_UTILITY:
Matt Menkee5bc4a562017-08-07 23:58:22534 // This needs to be larger for the network service.
535 memory_size = 256 << 10; // 256 KiB
bcwhite2496c83e2016-08-29 17:29:25536 metrics_name = "UtilityMetrics";
537 break;
538
539 case PROCESS_TYPE_ZYGOTE:
bcwhite867f45532017-01-05 17:29:02540 memory_size = 64 << 10; // 64 KiB
bcwhite2496c83e2016-08-29 17:29:25541 metrics_name = "ZygoteMetrics";
542 break;
543
544 case PROCESS_TYPE_SANDBOX_HELPER:
bcwhite867f45532017-01-05 17:29:02545 memory_size = 64 << 10; // 64 KiB
bcwhite2496c83e2016-08-29 17:29:25546 metrics_name = "SandboxHelperMetrics";
547 break;
548
bcwhiteb58a5fe2016-08-22 16:25:56549 case PROCESS_TYPE_GPU:
Sadrul Habib Chowdhury2353ca522018-08-15 15:53:26550 // This needs to be larger for the display-compositor in the gpu process.
551 memory_size = 256 << 10; // 256 KiB
bcwhiteb58a5fe2016-08-22 16:25:56552 metrics_name = "GpuMetrics";
553 break;
554
bcwhite2496c83e2016-08-29 17:29:25555 case PROCESS_TYPE_PPAPI_PLUGIN:
bcwhite867f45532017-01-05 17:29:02556 memory_size = 64 << 10; // 64 KiB
bcwhite2496c83e2016-08-29 17:29:25557 metrics_name = "PpapiPluginMetrics";
558 break;
559
560 case PROCESS_TYPE_PPAPI_BROKER:
bcwhite867f45532017-01-05 17:29:02561 memory_size = 64 << 10; // 64 KiB
bcwhite2496c83e2016-08-29 17:29:25562 metrics_name = "PpapiBrokerMetrics";
563 break;
564
bcwhiteb58a5fe2016-08-22 16:25:56565 default:
bcwhitec600ac12017-07-12 13:37:13566 // Report new processes. "Custom" ones are renumbered to 1000+ so that
567 // they won't conflict with any standard ones in the future.
568 int process_type = data_.process_type;
569 if (process_type >= PROCESS_TYPE_CONTENT_END)
570 process_type += 1000 - PROCESS_TYPE_CONTENT_END;
Ilya Sherman1c811db2017-12-14 10:36:18571 base::UmaHistogramSparse(
bcwhitec600ac12017-07-12 13:37:13572 "UMA.SubprocessMetricsProvider.UntrackedProcesses", process_type);
bcwhiteb58a5fe2016-08-22 16:25:56573 return;
574 }
575
576 // Create the shared memory segment and attach an allocator to it.
577 // Mapping the memory shouldn't fail but be safe if it does; everything
578 // will continue to work but just as if persistence weren't available.
Alex Ilin30e7d062019-02-21 12:24:53579 base::WritableSharedMemoryRegion shm_region =
580 base::WritableSharedMemoryRegion::Create(memory_size);
581 base::WritableSharedMemoryMapping shm_mapping = shm_region.Map();
582 if (!shm_region.IsValid() || !shm_mapping.IsValid())
bcwhiteb58a5fe2016-08-22 16:25:56583 return;
Alex Ilin30e7d062019-02-21 12:24:53584 metrics_allocator_ =
585 std::make_unique<base::WritableSharedPersistentMemoryAllocator>(
586 std::move(shm_mapping), static_cast<uint64_t>(data_.id),
587 metrics_name);
588 metrics_shared_region_ = std::move(shm_region);
bcwhiteb58a5fe2016-08-22 16:25:56589}
590
591void BrowserChildProcessHostImpl::ShareMetricsAllocatorToProcess() {
592 if (metrics_allocator_) {
Nicholas Verne91bf4a632017-10-12 21:14:24593 HistogramController::GetInstance()->SetHistogramMemory<ChildProcessHost>(
Alex Ilin30e7d062019-02-21 12:24:53594 GetHost(), std::move(metrics_shared_region_));
Nicholas Verne91bf4a632017-10-12 21:14:24595 } else {
596 HistogramController::GetInstance()->SetHistogramMemory<ChildProcessHost>(
Alex Ilin30e7d062019-02-21 12:24:53597 GetHost(), base::WritableSharedMemoryRegion());
bcwhiteb58a5fe2016-08-22 16:25:56598 }
599}
600
wfh3adf87d2016-05-03 23:26:06601void BrowserChildProcessHostImpl::OnProcessLaunchFailed(int error_code) {
602 delegate_->OnProcessLaunchFailed(error_code);
amistry012289f2016-04-01 00:56:37603 notify_child_disconnected_ = false;
[email protected]fa01e472014-02-11 14:45:35604 delete delegate_; // Will delete us
605}
606
Min Qineb961902019-03-16 08:08:22607#if defined(OS_ANDROID)
608bool BrowserChildProcessHostImpl::CanUseWarmUpConnection() {
609 return can_use_warm_up_connection_;
610}
611#endif
612
[email protected]4c01d4992012-01-23 23:33:01613void BrowserChildProcessHostImpl::OnProcessLaunched() {
afakhry9cc79002015-10-22 19:25:15614 DCHECK_CURRENTLY_ON(BrowserThread::IO);
615
rvargas079d1842014-10-17 22:32:16616 const base::Process& process = child_process_->GetProcess();
617 DCHECK(process.IsValid());
[email protected]162a9fd2013-03-06 20:47:49618
rockotfe2fecc2017-01-19 20:16:19619 if (child_connection_)
David Bienvenuf47de5f12019-02-21 19:46:23620 child_connection_->SetProcess(process.Duplicate());
rockotfe2fecc2017-01-19 20:16:19621
jam3c8c50c2015-11-25 18:48:29622#if defined(OS_WIN)
[email protected]162a9fd2013-03-06 20:47:49623 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the
624 // child process exits. This watcher is stopped once the IPC channel is
625 // connected and the exit of the child process is detecter by an error on the
626 // IPC channel thereafter.
rvargas079d1842014-10-17 22:32:16627 DCHECK(!early_exit_watcher_.GetWatchedObject());
jam7fab1082015-09-29 02:26:18628 early_exit_watcher_.StartWatchingOnce(process.Handle(), this);
[email protected]162a9fd2013-03-06 20:47:49629#endif
630
Francois Doray884da022018-10-30 23:45:58631 data_.SetProcess(process.Duplicate());
[email protected]4967f792012-01-20 22:14:40632 delegate_->OnProcessLaunched();
afakhry9cc79002015-10-22 19:25:15633
634 if (is_channel_connected_) {
Eric Seckler8652dcd52018-09-20 10:42:28635 base::PostTaskWithTraits(
636 FROM_HERE, {BrowserThread::UI},
Bruce Dawson02f07de2018-07-31 17:28:26637 base::BindOnce(&NotifyProcessLaunchedAndConnected, data_.Duplicate()));
afakhry9cc79002015-10-22 19:25:15638 }
639}
640
641bool BrowserChildProcessHostImpl::IsProcessLaunched() const {
642 DCHECK_CURRENTLY_ON(BrowserThread::IO);
643
644 return child_process_.get() && child_process_->GetProcess().IsValid();
[email protected]d27893f62010-07-03 05:47:42645}
[email protected]130757672012-10-24 00:26:19646
rockot229fb28e2016-06-16 04:46:16647// static
648void BrowserChildProcessHostImpl::OnMojoError(
649 base::WeakPtr<BrowserChildProcessHostImpl> process,
650 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
651 const std::string& error) {
652 if (!task_runner->BelongsToCurrentThread()) {
653 task_runner->PostTask(
tzik4fea24af2017-08-23 11:41:47654 FROM_HERE, base::BindOnce(&BrowserChildProcessHostImpl::OnMojoError,
655 process, task_runner, error));
olka91f1d412016-11-21 15:24:53656 return;
rockot229fb28e2016-06-16 04:46:16657 }
658 if (!process)
659 return;
Wei-Yin Chen (陳威尹)223326c2017-07-21 02:08:28660 HistogramBadMessageTerminated(
661 static_cast<ProcessType>(process->data_.process_type));
rockot229fb28e2016-06-16 04:46:16662 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
663 switches::kDisableKillAfterBadIPC)) {
664 return;
665 }
666 LOG(ERROR) << "Terminating child process for bad Mojo message: " << error;
667
Yuzhu Shen32fcad72017-09-14 23:12:37668 // Create a memory dump with the error message captured in a crash key value.
669 // This will make it easy to determine details about what interface call
670 // failed.
Robert Sesek1419427e2017-12-07 15:01:32671 base::debug::ScopedCrashKeyString scoped_error_key(
672 bad_message::GetMojoErrorCrashKey(), error);
rockot229fb28e2016-06-16 04:46:16673 base::debug::DumpWithoutCrashing();
Bo Liue06143912018-04-20 20:42:30674 process->child_process_->Terminate(RESULT_CODE_KILLED_BAD_MESSAGE);
rockot229fb28e2016-06-16 04:46:16675}
676
[email protected]162a9fd2013-03-06 20:47:49677#if defined(OS_WIN)
678
rvargas079d1842014-10-17 22:32:16679void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) {
[email protected]162a9fd2013-03-06 20:47:49680 OnChildDisconnected();
681}
682
683#endif
684
[email protected]130757672012-10-24 00:26:19685} // namespace content