blob: c9cf76bac9836f4b33952e5dd0d612b1634905cd [file] [log] [blame]
[email protected]5c41e6e12012-03-17 02:20:461// 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]4734d0b2011-12-03 07:10:445#include "content/common/child_process_host_impl.h"
[email protected]d27893f62010-07-03 05:47:426
[email protected]4306c3792011-12-02 01:57:537#include <limits>
8
[email protected]3cb7cc9532014-01-08 22:55:519#include "base/atomic_sequence_num.h"
[email protected]d27893f62010-07-03 05:47:4210#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5211#include "base/files/file_path.h"
ssid1050d802015-07-28 20:28:1412#include "base/hash.h"
[email protected]8c40f322011-08-24 03:33:3613#include "base/logging.h"
[email protected]835d7c82010-10-14 04:38:3814#include "base/metrics/histogram.h"
reveman22dd9292014-10-13 20:52:0515#include "base/numerics/safe_math.h"
[email protected]d27893f62010-07-03 05:47:4216#include "base/path_service.h"
[email protected]71ed8e022013-07-25 14:39:5717#include "base/process/process_metrics.h"
[email protected]4306c3792011-12-02 01:57:5318#include "base/rand_util.h"
[email protected]30fe1f92013-06-12 16:34:3419#include "base/strings/stringprintf.h"
erikchen5708aae2015-09-14 17:45:1220#include "base/synchronization/lock.h"
[email protected]a5f28b42011-01-17 10:30:1321#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
[email protected]ff47b2962011-03-07 23:51:4922#include "content/common/child_process_messages.h"
reveman22dd9292014-10-13 20:52:0523#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
[email protected]4cb43102011-12-02 20:24:4924#include "content/public/common/child_process_host_delegate.h"
[email protected]5d921d4c2011-10-21 22:26:1425#include "content/public/common/content_paths.h"
[email protected]c08950d22011-10-13 22:20:2926#include "content/public/common/content_switches.h"
erikchen87397e02015-10-10 01:10:2427#include "ipc/attachment_broker.h"
[email protected]5c41e6e12012-03-17 02:20:4628#include "ipc/ipc_channel.h"
[email protected]a83d42292010-08-17 22:51:1029#include "ipc/ipc_logging.h"
[email protected]74122042014-04-25 00:07:3030#include "ipc/message_filter.h"
[email protected]d27893f62010-07-03 05:47:4231
32#if defined(OS_LINUX)
33#include "base/linux_util.h"
[email protected]e35c9a82011-12-01 18:48:4134#elif defined(OS_WIN)
35#include "content/common/font_cache_dispatcher_win.h"
[email protected]d27893f62010-07-03 05:47:4236#endif // OS_LINUX
37
[email protected]8c40f322011-08-24 03:33:3638namespace {
39
[email protected]3cb7cc9532014-01-08 22:55:5140// Global atomic to generate child process unique IDs.
41base::StaticAtomicSequenceNumber g_unique_id;
[email protected]8c40f322011-08-24 03:33:3642
43} // namespace
[email protected]8c40f322011-08-24 03:33:3644
[email protected]4734d0b2011-12-03 07:10:4445namespace content {
[email protected]d27893f62010-07-03 05:47:4246
[email protected]3cb7cc9532014-01-08 22:55:5147int ChildProcessHost::kInvalidUniqueID = -1;
[email protected]d7c7c98a2012-07-12 21:27:4448
ssid1050d802015-07-28 20:28:1449uint64 ChildProcessHost::kBrowserTracingProcessId =
50 std::numeric_limits<uint64>::max();
51
[email protected]4734d0b2011-12-03 07:10:4452// static
53ChildProcessHost* ChildProcessHost::Create(ChildProcessHostDelegate* delegate) {
54 return new ChildProcessHostImpl(delegate);
[email protected]d27893f62010-07-03 05:47:4255}
56
57// static
[email protected]a7329162013-02-07 19:21:4858base::FilePath ChildProcessHost::GetChildPath(int flags) {
59 base::FilePath child_path;
[email protected]d27893f62010-07-03 05:47:4260
[email protected]479278702014-08-11 20:32:0961 child_path = base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
[email protected]d27893f62010-07-03 05:47:4262 switches::kBrowserSubprocessPath);
[email protected]d27893f62010-07-03 05:47:4263
[email protected]d27893f62010-07-03 05:47:4264#if defined(OS_LINUX)
65 // Use /proc/self/exe rather than our known binary path so updates
66 // can't swap out the binary from underneath us.
[email protected]a5f28b42011-01-17 10:30:1367 // When running under Valgrind, forking /proc/self/exe ends up forking the
68 // Valgrind executable, which then crashes. However, it's almost safe to
69 // assume that the updates won't happen while testing with Valgrind tools.
[email protected]bfd47482011-08-24 13:57:2670 if (child_path.empty() && flags & CHILD_ALLOW_SELF && !RunningOnValgrind())
[email protected]a7329162013-02-07 19:21:4871 child_path = base::FilePath(base::kProcSelfExe);
[email protected]d27893f62010-07-03 05:47:4272#endif
73
74 // On most platforms, the child executable is the same as the current
75 // executable.
[email protected]bfd47482011-08-24 13:57:2676 if (child_path.empty())
[email protected]dcc72db2013-01-02 00:44:1877 PathService::Get(CHILD_PROCESS_EXE, &child_path);
[email protected]d27893f62010-07-03 05:47:4278 return child_path;
79}
80
[email protected]4734d0b2011-12-03 07:10:4481ChildProcessHostImpl::ChildProcessHostImpl(ChildProcessHostDelegate* delegate)
82 : delegate_(delegate),
[email protected]4734d0b2011-12-03 07:10:4483 opening_channel_(false) {
84#if defined(OS_WIN)
85 AddFilter(new FontCacheDispatcher());
86#endif
87}
88
89ChildProcessHostImpl::~ChildProcessHostImpl() {
erikchen1bfccba2015-07-31 01:09:2790#if USE_ATTACHMENT_BROKER
erikchend8a3d9022015-10-22 20:02:0291 IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel(
92 channel_.get());
erikchen1bfccba2015-07-31 01:09:2793#endif
[email protected]4734d0b2011-12-03 07:10:4494 for (size_t i = 0; i < filters_.size(); ++i) {
95 filters_[i]->OnChannelClosing();
96 filters_[i]->OnFilterRemoved();
97 }
[email protected]4734d0b2011-12-03 07:10:4498}
99
[email protected]74122042014-04-25 00:07:30100void ChildProcessHostImpl::AddFilter(IPC::MessageFilter* filter) {
[email protected]4734d0b2011-12-03 07:10:44101 filters_.push_back(filter);
102
[email protected]59383c782013-04-17 16:43:27103 if (channel_)
[email protected]4734d0b2011-12-03 07:10:44104 filter->OnFilterAdded(channel_.get());
105}
106
107void ChildProcessHostImpl::ForceShutdown() {
[email protected]bdae9812011-10-15 00:33:03108 Send(new ChildProcessMsg_Shutdown());
109}
[email protected]91443fc2010-07-14 05:08:46110
[email protected]4734d0b2011-12-03 07:10:44111std::string ChildProcessHostImpl::CreateChannel() {
[email protected]5c41e6e12012-03-17 02:20:46112 channel_id_ = IPC::Channel::GenerateVerifiedChannelID(std::string());
erikchen5708aae2015-09-14 17:45:12113 channel_ = IPC::Channel::CreateServer(channel_id_, this);
[email protected]d27893f62010-07-03 05:47:42114 if (!channel_->Connect())
[email protected]4734d0b2011-12-03 07:10:44115 return std::string();
erikchen1bfccba2015-07-31 01:09:27116#if USE_ATTACHMENT_BROKER
erikchend8a3d9022015-10-22 20:02:02117 IPC::AttachmentBroker::GetGlobal()->RegisterCommunicationChannel(
118 channel_.get());
erikchen1bfccba2015-07-31 01:09:27119#endif
[email protected]d27893f62010-07-03 05:47:42120
[email protected]8e2b6472010-12-15 22:19:48121 for (size_t i = 0; i < filters_.size(); ++i)
122 filters_[i]->OnFilterAdded(channel_.get());
123
[email protected]91443fc2010-07-14 05:08:46124 // Make sure these messages get sent first.
125#if defined(IPC_MESSAGE_LOG_ENABLED)
[email protected]8e8bb6d2010-12-13 08:18:55126 bool enabled = IPC::Logging::GetInstance()->Enabled();
[email protected]ff47b2962011-03-07 23:51:49127 Send(new ChildProcessMsg_SetIPCLoggingEnabled(enabled));
[email protected]91443fc2010-07-14 05:08:46128#endif
129
[email protected]d27893f62010-07-03 05:47:42130 opening_channel_ = true;
131
[email protected]4734d0b2011-12-03 07:10:44132 return channel_id_;
[email protected]d27893f62010-07-03 05:47:42133}
134
[email protected]4734d0b2011-12-03 07:10:44135bool ChildProcessHostImpl::IsChannelOpening() {
136 return opening_channel_;
137}
138
139#if defined(OS_POSIX)
morritaa409ccc2014-10-20 23:53:25140base::ScopedFD ChildProcessHostImpl::TakeClientFileDescriptor() {
[email protected]4734d0b2011-12-03 07:10:44141 return channel_->TakeClientFileDescriptor();
142}
143#endif
144
145bool ChildProcessHostImpl::Send(IPC::Message* message) {
[email protected]59383c782013-04-17 16:43:27146 if (!channel_) {
[email protected]8e2b6472010-12-15 22:19:48147 delete message;
[email protected]d27893f62010-07-03 05:47:42148 return false;
149 }
[email protected]8e2b6472010-12-15 22:19:48150 return channel_->Send(message);
[email protected]d27893f62010-07-03 05:47:42151}
152
[email protected]4734d0b2011-12-03 07:10:44153void ChildProcessHostImpl::AllocateSharedMemory(
[email protected]3f892832013-01-11 03:23:59154 size_t buffer_size, base::ProcessHandle child_process_handle,
[email protected]bdae9812011-10-15 00:33:03155 base::SharedMemoryHandle* shared_memory_handle) {
156 base::SharedMemory shared_buf;
[email protected]e607e2c12013-09-13 09:46:58157 if (!shared_buf.CreateAnonymous(buffer_size)) {
[email protected]bdae9812011-10-15 00:33:03158 *shared_memory_handle = base::SharedMemory::NULLHandle();
[email protected]e607e2c12013-09-13 09:46:58159 NOTREACHED() << "Cannot create shared memory buffer";
[email protected]bdae9812011-10-15 00:33:03160 return;
161 }
162 shared_buf.GiveToProcess(child_process_handle, shared_memory_handle);
163}
164
[email protected]4734d0b2011-12-03 07:10:44165int ChildProcessHostImpl::GenerateChildProcessUniqueId() {
[email protected]4306c3792011-12-02 01:57:53166 // This function must be threadsafe.
[email protected]d7c7c98a2012-07-12 21:27:44167 //
[email protected]3cb7cc9532014-01-08 22:55:51168 // Historically, this function returned ids started with 1, so in several
169 // places in the code a value of 0 (rather than kInvalidUniqueID) was used as
170 // an invalid value. So we retain those semantics.
171 int id = g_unique_id.GetNext() + 1;
[email protected]d7c7c98a2012-07-12 21:27:44172
[email protected]3cb7cc9532014-01-08 22:55:51173 CHECK_NE(0, id);
174 CHECK_NE(kInvalidUniqueID, id);
[email protected]d7c7c98a2012-07-12 21:27:44175
176 return id;
[email protected]4306c3792011-12-02 01:57:53177}
178
ssid1050d802015-07-28 20:28:14179uint64 ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
180 int child_process_id) {
181 // In single process mode, all the children are hosted in the same process,
182 // therefore the generated memory dump guids should not be conditioned by the
183 // child process id. The clients need not be aware of SPM and the conversion
184 // takes care of the SPM special case while translating child process ids to
185 // tracing process ids.
186 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
187 switches::kSingleProcess))
188 return ChildProcessHost::kBrowserTracingProcessId;
189
190 // The hash value is incremented so that the tracing id is never equal to
191 // MemoryDumpManager::kInvalidTracingProcessId.
192 return static_cast<uint64>(
193 base::Hash(reinterpret_cast<const char*>(&child_process_id),
194 sizeof(child_process_id))) +
195 1;
196}
197
[email protected]4734d0b2011-12-03 07:10:44198bool ChildProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
[email protected]d27893f62010-07-03 05:47:42199#ifdef IPC_MESSAGE_LOG_ENABLED
[email protected]8e8bb6d2010-12-13 08:18:55200 IPC::Logging* logger = IPC::Logging::GetInstance();
[email protected]d27893f62010-07-03 05:47:42201 if (msg.type() == IPC_LOGGING_ID) {
202 logger->OnReceivedLoggingMessage(msg);
[email protected]a95986a82010-12-24 06:19:28203 return true;
[email protected]d27893f62010-07-03 05:47:42204 }
205
206 if (logger->Enabled())
207 logger->OnPreDispatchMessage(msg);
208#endif
209
[email protected]8e2b6472010-12-15 22:19:48210 bool handled = false;
[email protected]4cb43102011-12-02 20:24:49211 for (size_t i = 0; i < filters_.size(); ++i) {
212 if (filters_[i]->OnMessageReceived(msg)) {
[email protected]8e2b6472010-12-15 22:19:48213 handled = true;
214 break;
[email protected]d27893f62010-07-03 05:47:42215 }
216 }
217
[email protected]bdae9812011-10-15 00:33:03218 if (!handled) {
[email protected]e5257432010-12-21 01:18:37219 handled = true;
[email protected]4734d0b2011-12-03 07:10:44220 IPC_BEGIN_MESSAGE_MAP(ChildProcessHostImpl, msg)
[email protected]bdae9812011-10-15 00:33:03221 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
222 OnShutdownRequest)
avief875b522015-09-11 20:58:51223 // NB: The SyncAllocateSharedMemory, SyncAllocateGpuMemoryBuffer, and
224 // DeletedGpuMemoryBuffer IPCs are handled here for non-renderer child
225 // processes. For renderer processes, they are handled in
226 // RenderMessageFilter.
[email protected]bdae9812011-10-15 00:33:03227 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateSharedMemory,
228 OnAllocateSharedMemory)
jam813663162015-03-26 16:46:29229 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer,
230 OnAllocateGpuMemoryBuffer)
reveman22dd9292014-10-13 20:52:05231 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DeletedGpuMemoryBuffer,
232 OnDeletedGpuMemoryBuffer)
[email protected]bdae9812011-10-15 00:33:03233 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]4cb43102011-12-02 20:24:49234 IPC_END_MESSAGE_MAP()
[email protected]e5257432010-12-21 01:18:37235
[email protected]bdae9812011-10-15 00:33:03236 if (!handled)
[email protected]4cb43102011-12-02 20:24:49237 handled = delegate_->OnMessageReceived(msg);
[email protected]bdae9812011-10-15 00:33:03238 }
[email protected]8e2b6472010-12-15 22:19:48239
[email protected]d27893f62010-07-03 05:47:42240#ifdef IPC_MESSAGE_LOG_ENABLED
241 if (logger->Enabled())
[email protected]4cb43102011-12-02 20:24:49242 logger->OnPostDispatchMessage(msg, channel_id_);
[email protected]d27893f62010-07-03 05:47:42243#endif
[email protected]a95986a82010-12-24 06:19:28244 return handled;
[email protected]d27893f62010-07-03 05:47:42245}
246
[email protected]4734d0b2011-12-03 07:10:44247void ChildProcessHostImpl::OnChannelConnected(int32 peer_pid) {
rvargas5779b382014-11-18 20:44:11248 if (!peer_process_.IsValid()) {
rvargas1c376a82015-03-16 23:03:52249 peer_process_ = base::Process::OpenWithExtraPrivileges(peer_pid);
rvargas747ff242015-01-17 02:46:47250 if (!peer_process_.IsValid())
251 peer_process_ = delegate_->GetProcess().Duplicate();
rvargas5779b382014-11-18 20:44:11252 DCHECK(peer_process_.IsValid());
[email protected]bdae9812011-10-15 00:33:03253 }
[email protected]4cb43102011-12-02 20:24:49254 opening_channel_ = false;
255 delegate_->OnChannelConnected(peer_pid);
256 for (size_t i = 0; i < filters_.size(); ++i)
257 filters_[i]->OnChannelConnected(peer_pid);
[email protected]d27893f62010-07-03 05:47:42258}
259
[email protected]4734d0b2011-12-03 07:10:44260void ChildProcessHostImpl::OnChannelError() {
[email protected]4cb43102011-12-02 20:24:49261 opening_channel_ = false;
262 delegate_->OnChannelError();
[email protected]d27893f62010-07-03 05:47:42263
[email protected]4cb43102011-12-02 20:24:49264 for (size_t i = 0; i < filters_.size(); ++i)
265 filters_[i]->OnChannelError();
[email protected]8e2b6472010-12-15 22:19:48266
[email protected]d27893f62010-07-03 05:47:42267 // This will delete host_, which will also destroy this!
[email protected]4cb43102011-12-02 20:24:49268 delegate_->OnChildDisconnected();
[email protected]d27893f62010-07-03 05:47:42269}
270
[email protected]ef2f6ba2014-05-15 23:06:07271void ChildProcessHostImpl::OnBadMessageReceived(const IPC::Message& message) {
272 delegate_->OnBadMessageReceived(message);
273}
274
[email protected]4734d0b2011-12-03 07:10:44275void ChildProcessHostImpl::OnAllocateSharedMemory(
[email protected]bdae9812011-10-15 00:33:03276 uint32 buffer_size,
277 base::SharedMemoryHandle* handle) {
rvargas5779b382014-11-18 20:44:11278 AllocateSharedMemory(buffer_size, peer_process_.Handle(), handle);
[email protected]bdae9812011-10-15 00:33:03279}
280
[email protected]4734d0b2011-12-03 07:10:44281void ChildProcessHostImpl::OnShutdownRequest() {
[email protected]4cb43102011-12-02 20:24:49282 if (delegate_->CanShutdown())
283 Send(new ChildProcessMsg_Shutdown());
[email protected]d27893f62010-07-03 05:47:42284}
[email protected]4734d0b2011-12-03 07:10:44285
[email protected]bc10f462013-10-22 23:13:09286void ChildProcessHostImpl::OnAllocateGpuMemoryBuffer(
ericrkc9984ebe2015-08-17 14:22:37287 gfx::GpuMemoryBufferId id,
[email protected]88105162013-12-05 01:02:12288 uint32 width,
289 uint32 height,
spangfcf5fab42015-08-04 19:25:35290 gfx::BufferFormat format,
291 gfx::BufferUsage usage,
jam813663162015-03-26 16:46:29292 gfx::GpuMemoryBufferHandle* handle) {
reveman22dd9292014-10-13 20:52:05293 // TODO(reveman): Add support for other types of GpuMemoryBuffers.
revemanbc2de2b2014-11-17 03:21:32294
295 // AllocateForChildProcess() will check if |width| and |height| are valid
296 // and handle failure in a controlled way when not. We just need to make
reveman485728ba2015-10-23 18:43:22297 // sure |usage| is supported here.
298 if (GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage)) {
jam813663162015-03-26 16:46:29299 *handle = GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
ericrkc9984ebe2015-08-17 14:22:37300 id, gfx::Size(width, height), format, peer_process_.Handle());
reveman22dd9292014-10-13 20:52:05301 }
reveman22dd9292014-10-13 20:52:05302}
303
304void ChildProcessHostImpl::OnDeletedGpuMemoryBuffer(
reveman510a6e02014-11-05 00:59:18305 gfx::GpuMemoryBufferId id,
alexst2992e562014-11-04 03:01:03306 uint32 sync_point) {
reveman22dd9292014-10-13 20:52:05307 // Note: Nothing to do here as ownership of shared memory backed
308 // GpuMemoryBuffers is passed with IPC.
309}
310
[email protected]4734d0b2011-12-03 07:10:44311} // namespace content