15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/child_process_launcher.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> // For std::pair. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/files/scoped_file.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h" 1658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/content_browser_client.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_descriptors.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/result_codes.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/sandboxed_process_launcher_delegate.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/sandbox_win.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/browser/bootstrap_sandbox_mac.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/mach_broker_mac.h" 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "sandbox/mac/bootstrap_sandbox.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_ANDROID) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/android/child_process_launcher_android.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/shared_memory.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_sandbox_host_linux.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/zygote_host/zygote_host_impl_linux.h" 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/common/child_process_sandbox_support_impl_linux.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/metrics/stats_table.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/posix/global_descriptors.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Having the functionality of ChildProcessLauncher be in an internal 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ref counted object allows us to automatically terminate the process when the 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parent class destructs, while still holding on to state that we need. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChildProcessLauncher::Context 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<ChildProcessLauncher::Context> { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Context() 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : client_(NULL), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_thread_id_(BrowserThread::UI), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit_code_(RESULT_CODE_NORMAL_EXIT), 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch starting_(true), 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(earthdok): Re-enable on CrOS http://crbug.com/360622 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch defined(THREAD_SANITIZER)) && !defined(OS_CHROMEOS) 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch terminate_child_on_shutdown_(false) 68c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#else 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch terminate_child_on_shutdown_(true) 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) , zygote_(false) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Launch( 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SandboxedProcessLauncherDelegate* delegate, 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine* cmd_line, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int child_process_id, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Client* client) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_ = client; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to close the client end of the IPC channel to reliably detect 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // child termination. We will close this fd after we create the child 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process which is asynchronous on Android. 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ipcfd_ = delegate->GetIpcFd(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Context::LaunchInternal, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(this), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_thread_id_, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_process_id, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd_line)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void OnChildProcessStarted( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this_object| is NOT thread safe. Only use it to post a task back. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Context> this_object, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::ID client_thread_id, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeTicks begin_launch_time, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordHistograms(begin_launch_time); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BrowserThread::CurrentlyOn(client_thread_id)) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is always invoked on the UI thread which is commonly the 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |client_thread_id| so we can shortcut one PostTask. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_object->Notify(handle); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_thread_id, FROM_HERE, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ChildProcessLauncher::Context::Notify, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_object, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetClient() { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need for locking as this function gets called on the same thread that 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // client_ would be used. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(client_thread_id_)); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_ = NULL; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_terminate_child_on_shutdown(bool terminate_on_shutdown) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) terminate_child_on_shutdown_ = terminate_on_shutdown; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<ChildProcessLauncher::Context>; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ChildProcessLauncher; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Context() { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Terminate(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void RecordHistograms(const base::TimeTicks begin_launch_time) { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordLaunchHistograms(launch_time); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ChildProcessLauncher::Context::RecordLaunchHistograms, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launch_time)); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void RecordLaunchHistograms(const base::TimeDelta launch_time) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Log the launch time, separating out the first one (which will likely be 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // slower due to the rest of the browser initializing at the same time). 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool done_first_launch = false; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (done_first_launch) { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) done_first_launch = true; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void LaunchInternal( 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |this_object| is NOT thread safe. Only use it to post a task back. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Context> this_object, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::ID client_thread_id, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int child_process_id, 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SandboxedProcessLauncherDelegate* delegate, 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine* cmd_line) { 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool launch_elevated = delegate->ShouldLaunchElevated(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_ANDROID) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int ipcfd = delegate->GetIpcFd(); 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_MACOSX) 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::EnvironmentMap env = delegate->GetEnvironment(); 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int ipcfd = delegate->GetIpcFd(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool use_zygote = delegate->ShouldUseZygote(); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::EnvironmentMap env = delegate->GetEnvironment(); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int ipcfd = delegate->GetIpcFd(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks begin_launch_time = base::TimeTicks::Now(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ProcessHandle handle = base::kNullProcessHandle; 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (launch_elevated) { 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::LaunchOptions options; 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) options.start_hidden = true; 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::LaunchElevatedProcess(*cmd_line, options, &handle); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handle = StartSandboxedProcess(delegate, cmd_line); 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#elif defined(OS_POSIX) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string process_type = 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd_line->GetSwitchValueASCII(switches::kProcessType); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<FileDescriptorInfo> files_to_register; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files_to_register.push_back( 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorInfo(kPrimaryIPCChannel, 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::FileDescriptor(ipcfd, false))); 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::StatsTable* stats_table = base::StatsTable::current(); 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (stats_table && 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::SharedMemory::IsHandleValid( 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stats_table->GetSharedMemoryHandle())) { 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) files_to_register.push_back( 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FileDescriptorInfo(kStatsTableSharedMemFd, 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stats_table->GetSharedMemoryHandle())); 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_ANDROID) 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Android WebView runs in single process, ensure that we never get here 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // when running in single process mode. 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContentClient()->browser()-> 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &files_to_register); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2274ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch StartChildProcess(cmd_line->argv(), child_process_id, files_to_register, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted, 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this_object, client_thread_id, begin_launch_time)); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle = base::kNullProcessHandle; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to close the client end of the IPC channel to reliably detect 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // child termination. 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD ipcfd_closer(ipcfd); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContentClient()->browser()-> 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &files_to_register); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_zygote) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files_to_register, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_type); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall through to the normal posix case below when we're not zygoting. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert FD mapping to FileHandleMappingVector 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::FileHandleMappingVector fds_to_map; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < files_to_register.size(); ++i) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fds_to_map.push_back(std::make_pair( 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files_to_register[i].fd.fd, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files_to_register[i].id + 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GlobalDescriptors::kBaseDescriptor)); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_type == switches::kRendererProcess) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int sandbox_fd = 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fds_to_map.push_back(std::make_pair( 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sandbox_fd, 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetSandboxFD())); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Actually launch the app. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::LaunchOptions options; 27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) options.environ = env; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.fds_to_remap = &fds_to_map; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Hold the MachBroker lock for the duration of LaunchProcess. The child 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // will send its task port to the parent almost immediately after startup. 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The Mach message will be delivered to the parent, but updating the 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // record of the launch will wait until after the placeholder PID is 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // inserted below. This ensures that while the child process may send its 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // port to the parent prior to the parent leaving LaunchProcess, the 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // order in which the record in MachBroker is updated is correct. 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MachBroker* broker = MachBroker::GetInstance(); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) broker->GetLock().Acquire(); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure the MachBroker is running, and inform it to expect a 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // check-in from the new process. 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) broker->EnsureRunning(); 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const int bootstrap_sandbox_policy = delegate->GetSandboxType(); 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (ShouldEnableBootstrapSandbox() && 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_sandbox_policy != SANDBOX_TYPE_INVALID) { 2916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) options.replacement_bootstrap_name = 2926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) GetBootstrapSandbox()->server_bootstrap_name(); 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetBootstrapSandbox()->PrepareToForkWithPolicy( 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_sandbox_policy); 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool launched = base::LaunchProcess(*cmd_line, options, &handle); 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!launched) 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) handle = base::kNullProcessHandle; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (ShouldEnableBootstrapSandbox() && 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_sandbox_policy != SANDBOX_TYPE_INVALID) { 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetBootstrapSandbox()->FinishedFork(handle); 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (launched) 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) broker->AddPlaceholderForPid(handle); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // After updating the broker, release the lock and let the child's 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // messasge be processed on the broker's thread. 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) broker->GetLock().Release(); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // else defined(OS_POSIX) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (handle) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordHistograms(begin_launch_time); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_thread_id, FROM_HERE, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Context::Notify, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_object.get(), 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_zygote, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle)); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_ANDROID) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Notify( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zygote, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally close the ipcfd 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::ScopedFD ipcfd_closer(ipcfd_); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) starting_ = false; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_.set_handle(handle); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handle) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to launch child process"; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zygote_ = zygote; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client_) { 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (handle) { 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_->OnProcessLaunched(); 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_->OnProcessLaunchFailed(); 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Terminate(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Terminate() { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!process_.handle()) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!terminate_child_on_shutdown_) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't this on the UI/IO threads. 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Context::TerminateInternal, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zygote_, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_.handle())); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_.set_handle(base::kNullProcessHandle); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SetProcessBackgrounded(base::ProcessHandle handle, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool background) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Process process(handle); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process.SetProcessBackgrounded(background); 384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_ANDROID) 385a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetChildProcessInForeground(handle, !background); 386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void TerminateInternal( 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zygote, 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(0) << "ChromeProcess: Stopping process with handle " << handle; 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopChildProcess(handle); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Process process(handle); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Client has gone away, so just kill the process. Using exit code 0 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // means that UMA won't treat this as a crash. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process.Terminate(RESULT_CODE_NORMAL_EXIT); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On POSIX, we must additionally reap the child. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (zygote) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the renderer was created via a zygote, we have to proxy the reaping 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // through the zygote process. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(handle); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !OS_MACOSX 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::EnsureProcessTerminated(handle); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_POSIX 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process.Close(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_ANDROID) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Client* client_; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::ID client_thread_id_; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Process process_; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TerminationStatus termination_status_; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int exit_code_; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool starting_; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Controls whether the child process should be terminated on browser 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shutdown. Default behavior is to terminate the child. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool terminate_child_on_shutdown_; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The fd to close after creating the process. 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ipcfd_; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_MACOSX) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool zygote_; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChildProcessLauncher::ChildProcessLauncher( 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SandboxedProcessLauncherDelegate* delegate, 4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine* cmd_line, 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int child_process_id, 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Client* client) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_ = new Context(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->Launch( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate, 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd_line, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_process_id, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChildProcessLauncher::~ChildProcessLauncher() { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->ResetClient(); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChildProcessLauncher::IsStarting() { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_->starting_; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::ProcessHandle ChildProcessLauncher::GetHandle() { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!context_->starting_); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_->process_.handle(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus( 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool known_dead, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* exit_code) { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle = context_->process_.handle(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle == base::kNullProcessHandle) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process is already gone, so return the cached termination status. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exit_code) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *exit_code = context_->exit_code_; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_->termination_status_; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_->zygote_) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->termination_status_ = ZygoteHostImpl::GetInstance()-> 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetTerminationStatus(handle, known_dead, &context_->exit_code_); 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (known_dead) { 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) context_->termination_status_ = 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::GetKnownDeadTerminationStatus(handle, &context_->exit_code_); 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#elif defined(OS_MACOSX) 482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (known_dead) { 483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) context_->termination_status_ = 484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::GetKnownDeadTerminationStatus(handle, &context_->exit_code_); 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#elif defined(OS_ANDROID) 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsChildProcessOomProtected(handle)) { 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) context_->termination_status_ = base::TERMINATION_STATUS_OOM_PROTECTED; 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->termination_status_ = 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetTerminationStatus(handle, &context_->exit_code_); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exit_code) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *exit_code = context_->exit_code_; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // POSIX: If the process crashed, then the kernel closed the socket 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for it and so the child has already died by the time we get 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. Since GetTerminationStatus called waitpid with WNOHANG, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it'll reap the process. However, if GetTerminationStatus didn't 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reap the child (because it was still running), we'll need to 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Terminate via ProcessWatcher. So we can't close the handle here. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context_->termination_status_ != base::TERMINATION_STATUS_STILL_RUNNING) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->process_.Close(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_->termination_status_; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildProcessLauncher::SetProcessBackgrounded(bool background) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind( 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &ChildProcessLauncher::Context::SetProcessBackgrounded, 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetHandle(), background)); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChildProcessLauncher::SetTerminateChildOnShutdown( 521effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool terminate_on_shutdown) { 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (context_.get()) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_->set_terminate_child_on_shutdown(terminate_on_shutdown); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 527