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

Side by Side Diff: content/browser/child_process_launcher.cc

Issue 1640123005: Revert of Have each SandboxedProcessLauncherDelegate maintain a zygote. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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/child_process_launcher.h ('k') | content/browser/ppapi_plugin_process_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 4
5 #include "content/browser/child_process_launcher.h" 5 #include "content/browser/child_process_launcher.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 21 matching lines...) Expand all
32 #include "content/browser/bootstrap_sandbox_manager_mac.h" 32 #include "content/browser/bootstrap_sandbox_manager_mac.h"
33 #include "content/browser/mach_broker_mac.h" 33 #include "content/browser/mach_broker_mac.h"
34 #include "sandbox/mac/bootstrap_sandbox.h" 34 #include "sandbox/mac/bootstrap_sandbox.h"
35 #include "sandbox/mac/pre_exec_delegate.h" 35 #include "sandbox/mac/pre_exec_delegate.h"
36 #elif defined(OS_ANDROID) 36 #elif defined(OS_ANDROID)
37 #include "base/android/jni_android.h" 37 #include "base/android/jni_android.h"
38 #include "content/browser/android/child_process_launcher_android.h" 38 #include "content/browser/android/child_process_launcher_android.h"
39 #elif defined(OS_POSIX) 39 #elif defined(OS_POSIX)
40 #include "base/memory/singleton.h" 40 #include "base/memory/singleton.h"
41 #include "content/browser/renderer_host/render_sandbox_host_linux.h" 41 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
42 #include "content/browser/zygote_host/zygote_communication_linux.h"
43 #include "content/browser/zygote_host/zygote_host_impl_linux.h" 42 #include "content/browser/zygote_host/zygote_host_impl_linux.h"
44 #include "content/common/child_process_sandbox_support_impl_linux.h" 43 #include "content/common/child_process_sandbox_support_impl_linux.h"
45 #include "content/public/browser/zygote_handle_linux.h"
46 #endif 44 #endif
47 45
48 #if defined(OS_POSIX) 46 #if defined(OS_POSIX)
49 #include "base/posix/global_descriptors.h" 47 #include "base/posix/global_descriptors.h"
50 #include "content/browser/file_descriptor_info_impl.h" 48 #include "content/browser/file_descriptor_info_impl.h"
51 #include "gin/v8_initializer.h" 49 #include "gin/v8_initializer.h"
52 #endif 50 #endif
53 51
54 namespace content { 52 namespace content {
55 53
56 namespace { 54 namespace {
57 55
58 typedef base::Callback<void(ZygoteHandle, 56 typedef base::Callback<void(bool,
59 #if defined(OS_ANDROID) 57 #if defined(OS_ANDROID)
60 base::ScopedFD, 58 base::ScopedFD,
61 #endif 59 #endif
62 base::Process)> NotifyCallback; 60 base::Process)> NotifyCallback;
63 61
64 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) { 62 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
65 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 63 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
66 // Log the launch time, separating out the first one (which will likely be 64 // Log the launch time, separating out the first one (which will likely be
67 // slower due to the rest of the browser initializing at the same time). 65 // slower due to the rest of the browser initializing at the same time).
68 static bool done_first_launch = false; 66 static bool done_first_launch = false;
(...skipping 13 matching lines...) Expand all
82 const base::TimeTicks begin_launch_time, 80 const base::TimeTicks begin_launch_time,
83 base::ScopedFD ipcfd, 81 base::ScopedFD ipcfd,
84 base::ProcessHandle handle) { 82 base::ProcessHandle handle) {
85 // This can be called on the launcher thread or UI thread. 83 // This can be called on the launcher thread or UI thread.
86 base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time; 84 base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time;
87 BrowserThread::PostTask( 85 BrowserThread::PostTask(
88 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 86 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
89 base::Bind(&RecordHistogramsOnLauncherThread, launch_time)); 87 base::Bind(&RecordHistogramsOnLauncherThread, launch_time));
90 88
91 base::Closure callback_on_client_thread( 89 base::Closure callback_on_client_thread(
92 base::Bind(callback, nullptr, base::Passed(&ipcfd), 90 base::Bind(callback, false, base::Passed(&ipcfd),
93 base::Passed(base::Process(handle)))); 91 base::Passed(base::Process(handle))));
94 if (BrowserThread::CurrentlyOn(client_thread_id)) { 92 if (BrowserThread::CurrentlyOn(client_thread_id)) {
95 callback_on_client_thread.Run(); 93 callback_on_client_thread.Run();
96 } else { 94 } else {
97 BrowserThread::PostTask( 95 BrowserThread::PostTask(
98 client_thread_id, FROM_HERE, callback_on_client_thread); 96 client_thread_id, FROM_HERE, callback_on_client_thread);
99 } 97 }
100 } 98 }
101 #endif 99 #endif
102 100
103 void LaunchOnLauncherThread(const NotifyCallback& callback, 101 void LaunchOnLauncherThread(const NotifyCallback& callback,
104 BrowserThread::ID client_thread_id, 102 BrowserThread::ID client_thread_id,
105 int child_process_id, 103 int child_process_id,
106 SandboxedProcessLauncherDelegate* delegate, 104 SandboxedProcessLauncherDelegate* delegate,
107 #if defined(OS_ANDROID) 105 #if defined(OS_ANDROID)
108 base::ScopedFD ipcfd, 106 base::ScopedFD ipcfd,
109 #endif 107 #endif
110 base::CommandLine* cmd_line) { 108 base::CommandLine* cmd_line) {
111 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 109 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
112 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); 110 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
113 #if !defined(OS_ANDROID)
114 ZygoteHandle zygote = nullptr;
115 #endif
116 #if defined(OS_WIN) 111 #if defined(OS_WIN)
112 bool use_zygote = false;
117 bool launch_elevated = delegate->ShouldLaunchElevated(); 113 bool launch_elevated = delegate->ShouldLaunchElevated();
118 #elif defined(OS_MACOSX) 114 #elif defined(OS_MACOSX)
115 bool use_zygote = false;
119 base::EnvironmentMap env = delegate->GetEnvironment(); 116 base::EnvironmentMap env = delegate->GetEnvironment();
120 base::ScopedFD ipcfd = delegate->TakeIpcFd(); 117 base::ScopedFD ipcfd = delegate->TakeIpcFd();
121 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 118 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
119 bool use_zygote = delegate->ShouldUseZygote();
122 base::EnvironmentMap env = delegate->GetEnvironment(); 120 base::EnvironmentMap env = delegate->GetEnvironment();
123 base::ScopedFD ipcfd = delegate->TakeIpcFd(); 121 base::ScopedFD ipcfd = delegate->TakeIpcFd();
124 #endif 122 #endif
125 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); 123 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line);
126 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); 124 base::TimeTicks begin_launch_time = base::TimeTicks::Now();
127 125
128 base::Process process; 126 base::Process process;
129 #if defined(OS_WIN) 127 #if defined(OS_WIN)
130 if (launch_elevated) { 128 if (launch_elevated) {
131 base::LaunchOptions options; 129 base::LaunchOptions options;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 StartChildProcess( 192 StartChildProcess(
195 cmd_line->argv(), child_process_id, std::move(files_to_register), regions, 193 cmd_line->argv(), child_process_id, std::move(files_to_register), regions,
196 base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id, 194 base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id,
197 begin_launch_time, base::Passed(&ipcfd))); 195 begin_launch_time, base::Passed(&ipcfd)));
198 196
199 #elif defined(OS_POSIX) 197 #elif defined(OS_POSIX)
200 // We need to close the client end of the IPC channel to reliably detect 198 // We need to close the client end of the IPC channel to reliably detect
201 // child termination. 199 // child termination.
202 200
203 #if !defined(OS_MACOSX) 201 #if !defined(OS_MACOSX)
204 ZygoteHandle* zygote_handle = delegate->GetZygote(); 202 if (use_zygote) {
205 // If |zygote_handle| is null, a zygote should not be used. 203 base::ProcessHandle handle = ZygoteHostImpl::GetInstance()->ForkRequest(
206 if (zygote_handle) {
207 // This code runs on the PROCESS_LAUNCHER thread so race conditions are not
208 // an issue with the lazy initialization.
209 if (*zygote_handle == nullptr) {
210 *zygote_handle = CreateZygote();
211 }
212 zygote = *zygote_handle;
213 base::ProcessHandle handle = zygote->ForkRequest(
214 cmd_line->argv(), std::move(files_to_register), process_type); 204 cmd_line->argv(), std::move(files_to_register), process_type);
215 process = base::Process(handle); 205 process = base::Process(handle);
216 } else 206 } else
217 // Fall through to the normal posix case below when we're not zygoting. 207 // Fall through to the normal posix case below when we're not zygoting.
218 #endif // !defined(OS_MACOSX) 208 #endif // !defined(OS_MACOSX)
219 { 209 {
220 // Convert FD mapping to FileHandleMappingVector 210 // Convert FD mapping to FileHandleMappingVector
221 base::FileHandleMappingVector fds_to_map = 211 base::FileHandleMappingVector fds_to_map =
222 files_to_register->GetMappingWithIDAdjustment( 212 files_to_register->GetMappingWithIDAdjustment(
223 base::GlobalDescriptors::kBaseDescriptor); 213 base::GlobalDescriptors::kBaseDescriptor);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 broker->GetLock().Release(); 272 broker->GetLock().Release();
283 #endif // defined(OS_MACOSX) 273 #endif // defined(OS_MACOSX)
284 } 274 }
285 #endif // else defined(OS_POSIX) 275 #endif // else defined(OS_POSIX)
286 #if !defined(OS_ANDROID) 276 #if !defined(OS_ANDROID)
287 if (process.IsValid()) { 277 if (process.IsValid()) {
288 RecordHistogramsOnLauncherThread(base::TimeTicks::Now() - 278 RecordHistogramsOnLauncherThread(base::TimeTicks::Now() -
289 begin_launch_time); 279 begin_launch_time);
290 } 280 }
291 BrowserThread::PostTask(client_thread_id, FROM_HERE, 281 BrowserThread::PostTask(client_thread_id, FROM_HERE,
292 base::Bind(callback, zygote, base::Passed(&process))); 282 base::Bind(callback,
283 use_zygote,
284 base::Passed(&process)));
293 #endif // !defined(OS_ANDROID) 285 #endif // !defined(OS_ANDROID)
294 } 286 }
295 287
296 void TerminateOnLauncherThread(ZygoteHandle zygote, base::Process process) { 288 void TerminateOnLauncherThread(bool zygote, base::Process process) {
297 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 289 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
298 #if defined(OS_ANDROID) 290 #if defined(OS_ANDROID)
299 VLOG(1) << "ChromeProcess: Stopping process with handle " 291 VLOG(1) << "ChromeProcess: Stopping process with handle "
300 << process.Handle(); 292 << process.Handle();
301 StopChildProcess(process.Handle()); 293 StopChildProcess(process.Handle());
302 #else 294 #else
303 // Client has gone away, so just kill the process. Using exit code 0 295 // Client has gone away, so just kill the process. Using exit code 0
304 // means that UMA won't treat this as a crash. 296 // means that UMA won't treat this as a crash.
305 process.Terminate(RESULT_CODE_NORMAL_EXIT, false); 297 process.Terminate(RESULT_CODE_NORMAL_EXIT, false);
306 // On POSIX, we must additionally reap the child. 298 // On POSIX, we must additionally reap the child.
307 #if defined(OS_POSIX) 299 #if defined(OS_POSIX)
308 #if !defined(OS_MACOSX) 300 #if !defined(OS_MACOSX)
309 if (zygote) { 301 if (zygote) {
310 // If the renderer was created via a zygote, we have to proxy the reaping 302 // If the renderer was created via a zygote, we have to proxy the reaping
311 // through the zygote process. 303 // through the zygote process.
312 zygote->EnsureProcessTerminated(process.Handle()); 304 ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(process.Handle());
313 } else 305 } else
314 #endif // !OS_MACOSX 306 #endif // !OS_MACOSX
315 base::EnsureProcessTerminated(std::move(process)); 307 base::EnsureProcessTerminated(std::move(process));
316 #endif // OS_POSIX 308 #endif // OS_POSIX
317 #endif // defined(OS_ANDROID) 309 #endif // defined(OS_ANDROID)
318 } 310 }
319 311
320 void SetProcessBackgroundedOnLauncherThread(base::Process process, 312 void SetProcessBackgroundedOnLauncherThread(base::Process process,
321 bool background) { 313 bool background) {
322 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 314 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
323 if (process.CanBackgroundProcesses()) { 315 if (process.CanBackgroundProcesses()) {
324 process.SetProcessBackgrounded(background); 316 process.SetProcessBackgrounded(background);
325 } 317 }
326 #if defined(OS_ANDROID) 318 #if defined(OS_ANDROID)
327 SetChildProcessInForeground(process.Handle(), !background); 319 SetChildProcessInForeground(process.Handle(), !background);
328 #endif 320 #endif
329 } 321 }
330 322
331 } // namespace 323 } // namespace
332 324
333 ChildProcessLauncher::ChildProcessLauncher( 325 ChildProcessLauncher::ChildProcessLauncher(
334 SandboxedProcessLauncherDelegate* delegate, 326 SandboxedProcessLauncherDelegate* delegate,
335 base::CommandLine* cmd_line, 327 base::CommandLine* cmd_line,
336 int child_process_id, 328 int child_process_id,
337 Client* client, 329 Client* client,
338 bool terminate_on_shutdown) 330 bool terminate_on_shutdown)
339 : client_(client), 331 : client_(client),
340 termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION), 332 termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION),
341 exit_code_(RESULT_CODE_NORMAL_EXIT), 333 exit_code_(RESULT_CODE_NORMAL_EXIT),
342 zygote_(nullptr), 334 zygote_(false),
343 starting_(true), 335 starting_(true),
344 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ 336 #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
345 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ 337 defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
346 defined(UNDEFINED_SANITIZER) 338 defined(UNDEFINED_SANITIZER)
347 terminate_child_on_shutdown_(false), 339 terminate_child_on_shutdown_(false),
348 #else 340 #else
349 terminate_child_on_shutdown_(terminate_on_shutdown), 341 terminate_child_on_shutdown_(terminate_on_shutdown),
350 #endif 342 #endif
351 weak_factory_(this) { 343 weak_factory_(this) {
352 DCHECK(CalledOnValidThread()); 344 DCHECK(CalledOnValidThread());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 #if defined(OS_ANDROID) 394 #if defined(OS_ANDROID)
403 base::Passed(&ipcfd), 395 base::Passed(&ipcfd),
404 #endif 396 #endif
405 cmd_line)); 397 cmd_line));
406 } 398 }
407 399
408 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { 400 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
409 DCHECK(CalledOnValidThread()); 401 DCHECK(CalledOnValidThread());
410 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 402 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
411 if (zygote_) { 403 if (zygote_) {
412 termination_status_ = zygote_->GetTerminationStatus( 404 termination_status_ = ZygoteHostImpl::GetInstance()->
413 process_.Handle(), known_dead, &exit_code_); 405 GetTerminationStatus(process_.Handle(), known_dead, &exit_code_);
414 } else if (known_dead) { 406 } else if (known_dead) {
415 termination_status_ = 407 termination_status_ =
416 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_); 408 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_);
417 } else { 409 } else {
418 #elif defined(OS_MACOSX) 410 #elif defined(OS_MACOSX)
419 if (known_dead) { 411 if (known_dead) {
420 termination_status_ = 412 termination_status_ =
421 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_); 413 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_);
422 } else { 414 } else {
423 #elif defined(OS_ANDROID) 415 #elif defined(OS_ANDROID)
(...skipping 12 matching lines...) Expand all
436 DCHECK(CalledOnValidThread()); 428 DCHECK(CalledOnValidThread());
437 base::Process to_pass = process_.Duplicate(); 429 base::Process to_pass = process_.Duplicate();
438 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 430 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
439 base::Bind(&SetProcessBackgroundedOnLauncherThread, 431 base::Bind(&SetProcessBackgroundedOnLauncherThread,
440 base::Passed(&to_pass), background)); 432 base::Passed(&to_pass), background));
441 } 433 }
442 434
443 void ChildProcessLauncher::DidLaunch( 435 void ChildProcessLauncher::DidLaunch(
444 base::WeakPtr<ChildProcessLauncher> instance, 436 base::WeakPtr<ChildProcessLauncher> instance,
445 bool terminate_on_shutdown, 437 bool terminate_on_shutdown,
446 ZygoteHandle zygote, 438 bool zygote,
447 #if defined(OS_ANDROID) 439 #if defined(OS_ANDROID)
448 base::ScopedFD ipcfd, 440 base::ScopedFD ipcfd,
449 #endif 441 #endif
450 base::Process process) { 442 base::Process process) {
451 if (!process.IsValid()) 443 if (!process.IsValid())
452 LOG(ERROR) << "Failed to launch child process"; 444 LOG(ERROR) << "Failed to launch child process";
453 445
454 if (instance.get()) { 446 if (instance.get()) {
455 instance->Notify(zygote, 447 instance->Notify(zygote,
456 #if defined(OS_ANDROID) 448 #if defined(OS_ANDROID)
457 std::move(ipcfd), 449 std::move(ipcfd),
458 #endif 450 #endif
459 std::move(process)); 451 std::move(process));
460 } else { 452 } else {
461 if (process.IsValid() && terminate_on_shutdown) { 453 if (process.IsValid() && terminate_on_shutdown) {
462 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So 454 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So
463 // don't this on the UI/IO threads. 455 // don't this on the UI/IO threads.
464 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 456 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
465 base::Bind(&TerminateOnLauncherThread, zygote, 457 base::Bind(&TerminateOnLauncherThread, zygote,
466 base::Passed(&process))); 458 base::Passed(&process)));
467 } 459 }
468 } 460 }
469 } 461 }
470 462
471 void ChildProcessLauncher::Notify(ZygoteHandle zygote, 463 void ChildProcessLauncher::Notify(
464 bool zygote,
472 #if defined(OS_ANDROID) 465 #if defined(OS_ANDROID)
473 base::ScopedFD ipcfd, 466 base::ScopedFD ipcfd,
474 #endif 467 #endif
475 base::Process process) { 468 base::Process process) {
476 DCHECK(CalledOnValidThread()); 469 DCHECK(CalledOnValidThread());
477 starting_ = false; 470 starting_ = false;
478 process_ = std::move(process); 471 process_ = std::move(process);
479 472
480 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 473 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
481 zygote_ = zygote; 474 zygote_ = zygote;
482 #endif 475 #endif
483 if (process_.IsValid()) { 476 if (process_.IsValid()) {
484 client_->OnProcessLaunched(); 477 client_->OnProcessLaunched();
485 } else { 478 } else {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 } 521 }
529 522
530 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest( 523 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest(
531 Client* client) { 524 Client* client) {
532 Client* ret = client_; 525 Client* ret = client_;
533 client_ = client; 526 client_ = client;
534 return ret; 527 return ret;
535 } 528 }
536 529
537 } // namespace content 530 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_launcher.h ('k') | content/browser/ppapi_plugin_process_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698