blob: c2839221ad4b22eb5b8c17b51671328918570687 [file] [log] [blame]
[email protected]f573ed6b2012-02-10 15:58:521// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/public/app/content_main_runner.h"
6
avi66a07722015-12-25 23:38:127#include <stddef.h>
[email protected]3422af12012-08-08 01:27:038#include <stdlib.h>
avi66a07722015-12-25 23:38:129#include <string.h>
dcheng6003e0b2016-04-09 18:42:3410
11#include <memory>
pmonette18d3ed32015-10-16 21:06:0612#include <string>
dchengf63a1252015-12-26 20:43:1313#include <utility>
leon.han79db18e2017-01-27 05:26:2614#include <vector>
pmonette18d3ed32015-10-16 21:06:0615
primianobe9d6fc2016-01-12 22:16:1116#include "base/allocator/allocator_check.h"
[email protected]237a14852012-04-28 02:56:3817#include "base/allocator/allocator_extension.h"
erikchenbf11b55a2017-02-10 01:34:4818#include "base/allocator/features.h"
[email protected]f573ed6b2012-02-10 15:58:5219#include "base/at_exit.h"
erikchen55edbff2016-05-03 23:53:1720#include "base/base_switches.h"
[email protected]f573ed6b2012-02-10 15:58:5221#include "base/command_line.h"
22#include "base/debug/debugger.h"
jam79dc59a2015-08-17 03:38:1623#include "base/debug/stack_trace.h"
erikchen55edbff2016-05-03 23:53:1724#include "base/feature_list.h"
[email protected]57999812013-02-24 05:40:5225#include "base/files/file_path.h"
[email protected]f573ed6b2012-02-10 15:58:5226#include "base/i18n/icu_util.h"
[email protected]c6681f32012-06-05 14:43:0127#include "base/lazy_instance.h"
[email protected]f573ed6b2012-02-10 15:58:5228#include "base/logging.h"
avi66a07722015-12-25 23:38:1229#include "base/macros.h"
[email protected]54ad01a2014-05-11 01:17:4730#include "base/memory/scoped_vector.h"
erikchen55edbff2016-05-03 23:53:1731#include "base/metrics/field_trial.h"
bcwhited723c252016-03-16 17:25:4132#include "base/metrics/histogram_base.h"
oth575f7fb52015-05-08 17:35:0033#include "base/metrics/statistics_recorder.h"
[email protected]433df472012-03-07 20:33:3934#include "base/path_service.h"
[email protected]54724e22013-07-25 13:02:1535#include "base/process/launch.h"
36#include "base/process/memory.h"
lawrencewu2c930822016-10-13 13:54:2537#include "base/process/process.h"
[email protected]54724e22013-07-25 13:02:1538#include "base/process/process_handle.h"
yiyaoliu9e6a5ab32015-03-18 18:04:3739#include "base/profiler/scoped_tracker.h"
[email protected]e37f55e2013-06-11 04:29:0040#include "base/strings/string_number_conversions.h"
41#include "base/strings/string_util.h"
42#include "base/strings/stringprintf.h"
primiano50b7444c2015-01-28 04:17:0043#include "base/trace_event/trace_event.h"
avi66a07722015-12-25 23:38:1244#include "build/build_config.h"
ssid69e84192017-02-16 14:32:4745#include "components/tracing/common/trace_startup.h"
jame1f453c2016-03-21 15:51:3446#include "content/app/mojo/mojo_init.h"
[email protected]f573ed6b2012-02-10 15:58:5247#include "content/common/set_process_title.h"
[email protected]1de7a172012-05-28 18:36:4348#include "content/common/url_schemes.h"
[email protected]8a820c82014-03-09 18:06:5849#include "content/public/app/content_main.h"
[email protected]f573ed6b2012-02-10 15:58:5250#include "content/public/app/content_main_delegate.h"
[email protected]f573ed6b2012-02-10 15:58:5251#include "content/public/common/content_client.h"
52#include "content/public/common/content_constants.h"
jcivellidad0cef2017-02-16 18:38:5953#include "content/public/common/content_descriptor_keys.h"
[email protected]f573ed6b2012-02-10 15:58:5254#include "content/public/common/content_paths.h"
55#include "content/public/common/content_switches.h"
56#include "content/public/common/main_function_params.h"
57#include "content/public/common/sandbox_init.h"
[email protected]4e9b3d52014-04-08 23:13:4558#include "ipc/ipc_descriptors.h"
[email protected]433df472012-03-07 20:33:3959#include "media/base/media.h"
brettw4b461082016-11-19 18:55:1660#include "ppapi/features/features.h"
jcivellidad0cef2017-02-16 18:38:5961#include "services/service_manager/public/cpp/shared_file_util.h"
[email protected]f573ed6b2012-02-10 15:58:5262#include "ui/base/ui_base_paths.h"
[email protected]57999812013-02-24 05:40:5263#include "ui/base/ui_base_switches.h"
[email protected]f573ed6b2012-02-10 15:58:5264
scottmg8f970b12017-01-20 19:37:5665#if defined(V8_USE_EXTERNAL_STARTUP_DATA) && \
66 !defined(CHROME_MULTIPLE_DLL_BROWSER)
oth05c26fde2015-04-05 14:30:5767#include "gin/v8_initializer.h"
baixo3a3c88a2014-10-28 11:52:2168#endif
69
[email protected]f573ed6b2012-02-10 15:58:5270#if defined(OS_WIN)
[email protected]f573ed6b2012-02-10 15:58:5271#include <malloc.h>
[email protected]57999812013-02-24 05:40:5272#include <cstring>
[email protected]6c72e092014-06-04 11:10:5173
georgesak28ad5e62015-04-16 09:25:1974#include "base/trace_event/trace_event_etw_export_win.h"
pmonette18d3ed32015-10-16 21:06:0675#include "base/win/process_startup_helper.h"
wfh48c487e62016-07-27 22:48:4776#include "sandbox/win/src/sandbox_types.h"
[email protected]75f6dea02014-06-11 12:13:2377#include "ui/base/win/atl_module.h"
robliao18e220e82016-04-19 16:47:1278#include "ui/display/win/dpi.h"
[email protected]f573ed6b2012-02-10 15:58:5279#elif defined(OS_MACOSX)
erikchenbf11b55a2017-02-10 01:34:4880#include "base/allocator/allocator_shim.h"
[email protected]f573ed6b2012-02-10 15:58:5281#include "base/mac/scoped_nsautorelease_pool.h"
[email protected]9dd90152013-08-02 22:09:1382#include "base/power_monitor/power_monitor_device_source.h"
ccameronc685e64c2015-05-12 07:05:1783#include "content/app/mac/mac_init.h"
[email protected]f573ed6b2012-02-10 15:58:5284#include "content/browser/mach_broker_mac.h"
85#include "content/common/sandbox_init_mac.h"
86#endif // OS_WIN
87
88#if defined(OS_POSIX)
89#include <signal.h>
90
jcivellidad0cef2017-02-16 18:38:5991#include "base/file_descriptor_store.h"
[email protected]613eef62012-11-09 23:46:5492#include "base/posix/global_descriptors.h"
[email protected]b3aabd342012-06-04 19:33:5693#include "content/public/common/content_descriptors.h"
[email protected]f573ed6b2012-02-10 15:58:5294
95#if !defined(OS_MACOSX)
96#include "content/public/common/zygote_fork_delegate_linux.h"
97#endif
[email protected]16caf2c22013-04-13 01:26:0798#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
99#include "content/zygote/zygote_main.h"
100#endif
[email protected]f573ed6b2012-02-10 15:58:52101
102#endif // OS_POSIX
103
davidbenee55ed442015-10-02 17:06:11104#if defined(USE_NSS_CERTS)
105#include "crypto/nss_util.h"
106#endif
107
jamce6dd2112017-02-15 19:31:42108#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
109#include "content/public/gpu/content_gpu_client.h"
110#include "content/public/renderer/content_renderer_client.h"
111#include "content/public/utility/content_utility_client.h"
112#endif
113
114#if !defined(CHROME_MULTIPLE_DLL_CHILD)
115#include "content/browser/browser_main.h"
116#include "content/public/browser/content_browser_client.h"
117#endif
118
sadrule0d5a0d2017-01-30 19:09:02119#if !defined(CHROME_MULTIPLE_DLL_BROWSER) && !defined(CHROME_MULTIPLE_DLL_CHILD)
tapted4091f2f2017-02-07 00:47:19120#include "content/browser/gpu/gpu_main_thread_factory.h"
jamce6dd2112017-02-15 19:31:42121#include "content/browser/renderer_host/render_process_host_impl.h"
122#include "content/browser/utility_process_host_impl.h"
123#include "content/gpu/in_process_gpu_thread.h"
124#include "content/renderer/in_process_renderer_thread.h"
125#include "content/utility/in_process_utility_thread.h"
sadrule0d5a0d2017-01-30 19:09:02126#endif
127
xhwang785a8342017-01-26 06:46:39128#if BUILDFLAG(ENABLE_PEPPER_CDMS)
129#include "content/common/media/cdm_host_files.h"
130#endif
131
[email protected]a31fe0f2012-05-08 19:28:51132namespace content {
[email protected]eb398192012-10-22 20:16:19133extern int GpuMain(const content::MainFunctionParams&);
brettw4b461082016-11-19 18:55:16134#if BUILDFLAG(ENABLE_PLUGINS)
[email protected]c997bc42014-04-11 18:25:58135#if !defined(OS_LINUX)
[email protected]91355a82012-10-21 19:52:47136extern int PluginMain(const content::MainFunctionParams&);
[email protected]c997bc42014-04-11 18:25:58137#endif
[email protected]91355a82012-10-21 19:52:47138extern int PpapiPluginMain(const MainFunctionParams&);
139extern int PpapiBrokerMain(const MainFunctionParams&);
[email protected]0106cde2013-02-27 02:16:38140#endif
[email protected]91355a82012-10-21 19:52:47141extern int RendererMain(const content::MainFunctionParams&);
142extern int UtilityMain(const MainFunctionParams&);
[email protected]e9ff79c2012-10-19 21:31:26143} // namespace content
[email protected]f573ed6b2012-02-10 15:58:52144
[email protected]c6681f32012-06-05 14:43:01145namespace content {
146
erikchen55edbff2016-05-03 23:53:17147namespace {
148
jcivelli15ffa462017-02-09 18:01:30149#if defined(V8_USE_EXTERNAL_STARTUP_DATA) && defined(OS_ANDROID)
150#if defined __LP64__
jcivellidad0cef2017-02-16 18:38:59151#define kV8SnapshotDataDescriptor kV8Snapshot64DataDescriptor
jcivelli15ffa462017-02-09 18:01:30152#else
jcivellidad0cef2017-02-16 18:38:59153#define kV8SnapshotDataDescriptor kV8Snapshot32DataDescriptor
jcivelli15ffa462017-02-09 18:01:30154#endif
155#endif
156
erikchen55edbff2016-05-03 23:53:17157// This sets up two singletons responsible for managing field trials. The
158// |field_trial_list| singleton lives on the stack and must outlive the Run()
159// method of the process.
160void InitializeFieldTrialAndFeatureList(
161 std::unique_ptr<base::FieldTrialList>* field_trial_list) {
162 const base::CommandLine& command_line =
163 *base::CommandLine::ForCurrentProcess();
erikchen55edbff2016-05-03 23:53:17164
165 // Initialize statistical testing infrastructure. We set the entropy
166 // provider to nullptr to disallow non-browser processes from creating
167 // their own one-time randomized trials; they should be created in the
168 // browser process.
169 field_trial_list->reset(new base::FieldTrialList(nullptr));
170
171 // Ensure any field trials in browser are reflected into the child
172 // process.
lawrencewuc4fe8802016-11-30 16:25:02173#if defined(OS_POSIX)
174 // On POSIX systems that use the zygote, we get the trials from a shared
175 // memory segment backed by an fd instead of the command line.
lawrencewu2c930822016-10-13 13:54:25176 base::FieldTrialList::CreateTrialsFromCommandLine(
lawrencewuc4fe8802016-11-30 16:25:02177 command_line, switches::kFieldTrialHandle, kFieldTrialDescriptor);
178#else
179 base::FieldTrialList::CreateTrialsFromCommandLine(
180 command_line, switches::kFieldTrialHandle, -1);
181#endif
erikchen55edbff2016-05-03 23:53:17182
183 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
lawrencewu5e03cd32016-12-05 16:23:28184 base::FieldTrialList::CreateFeaturesFromCommandLine(
185 command_line, switches::kEnableFeatures, switches::kDisableFeatures,
186 feature_list.get());
erikchen55edbff2016-05-03 23:53:17187 base::FeatureList::SetInstance(std::move(feature_list));
188}
189
jcivelli15ffa462017-02-09 18:01:30190void InitializeV8IfNeeded(
191 const base::CommandLine& command_line,
192 const std::string& process_type) {
193 if (process_type == switches::kGpuProcess)
194 return;
195
196#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
197#if defined(OS_POSIX) && !defined(OS_MACOSX)
jcivellidad0cef2017-02-16 18:38:59198 base::FileDescriptorStore& file_descriptor_store =
199 base::FileDescriptorStore::GetInstance();
200 base::MemoryMappedFile::Region region;
201 base::ScopedFD v8_snapshot_fd =
202 file_descriptor_store.MaybeTakeFD(kV8SnapshotDataDescriptor, &region);
203 if (v8_snapshot_fd.is_valid()) {
204 gin::V8Initializer::LoadV8SnapshotFromFD(v8_snapshot_fd.get(),
205 region.offset, region.size);
jcivelli15ffa462017-02-09 18:01:30206 } else {
207 gin::V8Initializer::LoadV8Snapshot();
208 }
jcivellidad0cef2017-02-16 18:38:59209 base::ScopedFD v8_natives_fd =
210 file_descriptor_store.MaybeTakeFD(kV8NativesDataDescriptor, &region);
211 if (v8_natives_fd.is_valid()) {
212 gin::V8Initializer::LoadV8NativesFromFD(v8_natives_fd.get(),
213 region.offset, region.size);
jcivelli15ffa462017-02-09 18:01:30214 } else {
215 gin::V8Initializer::LoadV8Natives();
216 }
217#else
218#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
219 gin::V8Initializer::LoadV8Snapshot();
220 gin::V8Initializer::LoadV8Natives();
221#endif // !CHROME_MULTIPLE_DLL_BROWSER
222#endif // OS_POSIX && !OS_MACOSX
223#endif // V8_USE_EXTERNAL_STARTUP_DATA
224}
225
erikchen55edbff2016-05-03 23:53:17226} // namespace
227
yoz774dcda2d2014-08-27 03:32:58228#if !defined(CHROME_MULTIPLE_DLL_CHILD)
[email protected]c6681f32012-06-05 14:43:01229base::LazyInstance<ContentBrowserClient>
230 g_empty_content_browser_client = LAZY_INSTANCE_INITIALIZER;
yoz774dcda2d2014-08-27 03:32:58231#endif // !CHROME_MULTIPLE_DLL_CHILD
232
jame1f453c2016-03-21 15:51:34233#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
kcwu08377ad2016-02-18 19:12:42234base::LazyInstance<ContentGpuClient>
235 g_empty_content_gpu_client = LAZY_INSTANCE_INITIALIZER;
[email protected]c6681f32012-06-05 14:43:01236base::LazyInstance<ContentRendererClient>
237 g_empty_content_renderer_client = LAZY_INSTANCE_INITIALIZER;
238base::LazyInstance<ContentUtilityClient>
239 g_empty_content_utility_client = LAZY_INSTANCE_INITIALIZER;
jame1f453c2016-03-21 15:51:34240#endif // !CHROME_MULTIPLE_DLL_BROWSER
[email protected]f573ed6b2012-02-10 15:58:52241
jame1f453c2016-03-21 15:51:34242#if defined(OS_POSIX)
[email protected]f573ed6b2012-02-10 15:58:52243
244// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
245void SetupSignalHandlers() {
246 // Sanitise our signal handling state. Signals that were ignored by our
247 // parent will also be ignored by us. We also inherit our parent's sigmask.
248 sigset_t empty_signal_set;
pmonette18d3ed32015-10-16 21:06:06249 CHECK_EQ(0, sigemptyset(&empty_signal_set));
250 CHECK_EQ(0, sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));
[email protected]f573ed6b2012-02-10 15:58:52251
252 struct sigaction sigact;
253 memset(&sigact, 0, sizeof(sigact));
254 sigact.sa_handler = SIG_DFL;
255 static const int signals_to_reset[] =
256 {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
257 SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP}; // SIGPIPE is set below.
258 for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
pmonette18d3ed32015-10-16 21:06:06259 CHECK_EQ(0, sigaction(signals_to_reset[i], &sigact, NULL));
[email protected]f573ed6b2012-02-10 15:58:52260 }
261
262 // Always ignore SIGPIPE. We check the return value of write().
pmonette18d3ed32015-10-16 21:06:06263 CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
[email protected]f573ed6b2012-02-10 15:58:52264}
265
jcivellidad0cef2017-02-16 18:38:59266void PopulateFDsFromCommandLine() {
267 const std::string& shared_file_param =
268 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
269 switches::kSharedFiles);
270 if (shared_file_param.empty())
271 return;
272
273 base::Optional<std::map<int, std::string>> shared_file_descriptors =
274 service_manager::ParseSharedFileSwitchValue(shared_file_param);
275 if (!shared_file_descriptors)
276 return;
277
278 for (const auto& descriptor : *shared_file_descriptors) {
279 base::MemoryMappedFile::Region region;
280 const std::string& key = descriptor.second;
281 base::ScopedFD fd = base::GlobalDescriptors::GetInstance()->TakeFD(
282 descriptor.first, &region);
283 base::FileDescriptorStore::GetInstance().Set(key, std::move(fd), region);
284 }
285}
286
jame1f453c2016-03-21 15:51:34287#endif // OS_POSIX
[email protected]f573ed6b2012-02-10 15:58:52288
sadrulf6fb2a72017-02-08 17:59:28289void CommonSubprocessInit() {
[email protected]f573ed6b2012-02-10 15:58:52290#if defined(OS_WIN)
291 // HACK: Let Windows know that we have started. This is needed to suppress
292 // the IDC_APPSTARTING cursor from being displayed for a prolonged period
293 // while a subprocess is starting.
294 PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
295 MSG msg;
296 PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
297#endif
298#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
299 // Various things break when you're using a locale where the decimal
300 // separator isn't a period. See e.g. bugs 22782 and 39964. For
301 // all processes except the browser process (where we call system
302 // APIs that may rely on the correct locale for formatting numbers
303 // when presenting them to the user), reset the locale for numeric
304 // formatting.
305 // Note that this is not correct for plugin processes -- they can
306 // surface UI -- but it's likely they get this wrong too so why not.
307 setlocale(LC_NUMERIC, "C");
308#endif
jam79dc59a2015-08-17 03:38:16309
sadrulf6fb2a72017-02-08 17:59:28310#if !defined(OFFICIAL_BUILD) && defined(OS_WIN)
jam79dc59a2015-08-17 03:38:16311 base::RouteStdioToConsole(false);
312 LoadLibraryA("dbghelp.dll");
313#endif
[email protected]f573ed6b2012-02-10 15:58:52314}
315
[email protected]c6681f32012-06-05 14:43:01316class ContentClientInitializer {
317 public:
318 static void Set(const std::string& process_type,
319 ContentMainDelegate* delegate) {
320 ContentClient* content_client = GetContentClient();
yoz774dcda2d2014-08-27 03:32:58321#if !defined(CHROME_MULTIPLE_DLL_CHILD)
[email protected]c6681f32012-06-05 14:43:01322 if (process_type.empty()) {
323 if (delegate)
324 content_client->browser_ = delegate->CreateContentBrowserClient();
325 if (!content_client->browser_)
326 content_client->browser_ = &g_empty_content_browser_client.Get();
327 }
yoz774dcda2d2014-08-27 03:32:58328#endif // !CHROME_MULTIPLE_DLL_CHILD
[email protected]c6681f32012-06-05 14:43:01329
jame1f453c2016-03-21 15:51:34330#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
boliu919267f2016-05-17 17:12:14331 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
kcwu08377ad2016-02-18 19:12:42332 if (process_type == switches::kGpuProcess ||
boliu919267f2016-05-17 17:12:14333 cmd->HasSwitch(switches::kSingleProcess) ||
334 (process_type.empty() && cmd->HasSwitch(switches::kInProcessGPU))) {
kcwu08377ad2016-02-18 19:12:42335 if (delegate)
336 content_client->gpu_ = delegate->CreateContentGpuClient();
337 if (!content_client->gpu_)
338 content_client->gpu_ = &g_empty_content_gpu_client.Get();
339 }
340
piman72dcbed92016-04-05 04:27:21341 if (process_type == switches::kRendererProcess ||
boliu919267f2016-05-17 17:12:14342 cmd->HasSwitch(switches::kSingleProcess)) {
[email protected]c6681f32012-06-05 14:43:01343 if (delegate)
344 content_client->renderer_ = delegate->CreateContentRendererClient();
345 if (!content_client->renderer_)
346 content_client->renderer_ = &g_empty_content_renderer_client.Get();
[email protected]54a83d32013-07-11 17:53:09347 }
348
349 if (process_type == switches::kUtilityProcess ||
boliu919267f2016-05-17 17:12:14350 cmd->HasSwitch(switches::kSingleProcess)) {
[email protected]c6681f32012-06-05 14:43:01351 if (delegate)
352 content_client->utility_ = delegate->CreateContentUtilityClient();
[email protected]56c248b2013-05-08 17:51:02353 // TODO(scottmg): http://crbug.com/237249 Should be in _child.
[email protected]c6681f32012-06-05 14:43:01354 if (!content_client->utility_)
355 content_client->utility_ = &g_empty_content_utility_client.Get();
356 }
jame1f453c2016-03-21 15:51:34357#endif // !CHROME_MULTIPLE_DLL_BROWSER
[email protected]c6681f32012-06-05 14:43:01358 }
359};
360
[email protected]f573ed6b2012-02-10 15:58:52361// We dispatch to a process-type-specific FooMain() based on a command-line
362// flag. This struct is used to build a table of (flag, main function) pairs.
363struct MainFunction {
364 const char* name;
[email protected]c6681f32012-06-05 14:43:01365 int (*function)(const MainFunctionParams&);
[email protected]f573ed6b2012-02-10 15:58:52366};
367
[email protected]e0825562012-05-10 01:50:47368#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]f573ed6b2012-02-10 15:58:52369// On platforms that use the zygote, we have a special subset of
370// subprocesses that are launched via the zygote. This function
371// fills in some process-launching bits around ZygoteMain().
372// Returns the exit code of the subprocess.
[email protected]c6681f32012-06-05 14:43:01373int RunZygote(const MainFunctionParams& main_function_params,
374 ContentMainDelegate* delegate) {
[email protected]f573ed6b2012-02-10 15:58:52375 static const MainFunction kMainFunctions[] = {
376 { switches::kRendererProcess, RendererMain },
brettw4b461082016-11-19 18:55:16377#if BUILDFLAG(ENABLE_PLUGINS)
[email protected]f573ed6b2012-02-10 15:58:52378 { switches::kPpapiPluginProcess, PpapiPluginMain },
[email protected]0106cde2013-02-27 02:16:38379#endif
[email protected]f573ed6b2012-02-10 15:58:52380 { switches::kUtilityProcess, UtilityMain },
381 };
382
leon.han79db18e2017-01-27 05:26:26383 std::vector<std::unique_ptr<ZygoteForkDelegate>> zygote_fork_delegates;
[email protected]433df472012-03-07 20:33:39384 if (delegate) {
[email protected]54ad01a2014-05-11 01:17:47385 delegate->ZygoteStarting(&zygote_fork_delegates);
chcunninghamfd11b3c2015-06-09 02:09:42386 media::InitializeMediaLibrary();
[email protected]433df472012-03-07 20:33:39387 }
[email protected]f573ed6b2012-02-10 15:58:52388
389 // This function call can return multiple times, once per fork().
dchengf63a1252015-12-26 20:43:13390 if (!ZygoteMain(main_function_params, std::move(zygote_fork_delegates)))
[email protected]f573ed6b2012-02-10 15:58:52391 return 1;
392
393 if (delegate) delegate->ZygoteForked();
394
395 // Zygote::HandleForkRequest may have reallocated the command
396 // line so update it here with the new version.
[email protected]479278702014-08-11 20:32:09397 const base::CommandLine& command_line =
398 *base::CommandLine::ForCurrentProcess();
[email protected]c6681f32012-06-05 14:43:01399 std::string process_type =
400 command_line.GetSwitchValueASCII(switches::kProcessType);
401 ContentClientInitializer::Set(process_type, delegate);
[email protected]f573ed6b2012-02-10 15:58:52402
xhwang785a8342017-01-26 06:46:39403#if BUILDFLAG(ENABLE_PEPPER_CDMS)
404 if (process_type != switches::kPpapiPluginProcess) {
405 DVLOG(1) << "Closing CDM files for non-ppapi process.";
406 CdmHostFiles::TakeGlobalInstance().reset();
407 } else {
408 DVLOG(1) << "Not closing CDM files for ppapi process.";
409 }
410#endif
411
[email protected]c6681f32012-06-05 14:43:01412 MainFunctionParams main_params(command_line);
[email protected]692a9542014-06-25 23:04:47413 main_params.zygote_child = true;
[email protected]f573ed6b2012-02-10 15:58:52414
erikchen55edbff2016-05-03 23:53:17415 std::unique_ptr<base::FieldTrialList> field_trial_list;
416 InitializeFieldTrialAndFeatureList(&field_trial_list);
417
[email protected]f573ed6b2012-02-10 15:58:52418 for (size_t i = 0; i < arraysize(kMainFunctions); ++i) {
419 if (process_type == kMainFunctions[i].name)
420 return kMainFunctions[i].function(main_params);
421 }
422
423 if (delegate)
424 return delegate->RunProcess(process_type, main_params);
425
426 NOTREACHED() << "Unknown zygote process type: " << process_type;
427 return 1;
428}
[email protected]956a692e2012-07-11 03:25:47429#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]f573ed6b2012-02-10 15:58:52430
[email protected]52819472013-11-24 22:49:55431static void RegisterMainThreadFactories() {
yoz774dcda2d2014-08-27 03:32:58432#if !defined(CHROME_MULTIPLE_DLL_BROWSER) && !defined(CHROME_MULTIPLE_DLL_CHILD)
[email protected]683f4272014-04-17 20:42:18433 UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(
[email protected]52819472013-11-24 22:49:55434 CreateInProcessUtilityThread);
[email protected]683f4272014-04-17 20:42:18435 RenderProcessHostImpl::RegisterRendererMainThreadFactory(
[email protected]52819472013-11-24 22:49:55436 CreateInProcessRendererThread);
tapted4091f2f2017-02-07 00:47:19437 content::RegisterGpuMainThreadFactory(CreateInProcessGpuThread);
[email protected]52819472013-11-24 22:49:55438#else
[email protected]479278702014-08-11 20:32:09439 base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
[email protected]52819472013-11-24 22:49:55440 if (command_line.HasSwitch(switches::kSingleProcess)) {
441 LOG(FATAL) <<
442 "--single-process is not supported in chrome multiple dll browser.";
443 }
444 if (command_line.HasSwitch(switches::kInProcessGPU)) {
445 LOG(FATAL) <<
446 "--in-process-gpu is not supported in chrome multiple dll browser.";
447 }
yoz774dcda2d2014-08-27 03:32:58448#endif // !CHROME_MULTIPLE_DLL_BROWSER && !CHROME_MULTIPLE_DLL_CHILD
[email protected]52819472013-11-24 22:49:55449}
450
[email protected]f573ed6b2012-02-10 15:58:52451// Run the FooMain() for a given process type.
452// If |process_type| is empty, runs BrowserMain().
453// Returns the exit code for this process.
454int RunNamedProcessTypeMain(
455 const std::string& process_type,
[email protected]c6681f32012-06-05 14:43:01456 const MainFunctionParams& main_function_params,
457 ContentMainDelegate* delegate) {
[email protected]f573ed6b2012-02-10 15:58:52458 static const MainFunction kMainFunctions[] = {
[email protected]c955a8d2013-08-06 02:51:15459#if !defined(CHROME_MULTIPLE_DLL_CHILD)
[email protected]f573ed6b2012-02-10 15:58:52460 { "", BrowserMain },
[email protected]1ff64292013-07-18 20:37:15461#endif
[email protected]c955a8d2013-08-06 02:51:15462#if !defined(CHROME_MULTIPLE_DLL_BROWSER)
brettw4b461082016-11-19 18:55:16463#if BUILDFLAG(ENABLE_PLUGINS)
[email protected]f573ed6b2012-02-10 15:58:52464 { switches::kPpapiPluginProcess, PpapiPluginMain },
465 { switches::kPpapiBrokerProcess, PpapiBrokerMain },
[email protected]1ff64292013-07-18 20:37:15466#endif // ENABLE_PLUGINS
[email protected]f573ed6b2012-02-10 15:58:52467 { switches::kUtilityProcess, UtilityMain },
[email protected]56c248b2013-05-08 17:51:02468 { switches::kRendererProcess, RendererMain },
[email protected]f573ed6b2012-02-10 15:58:52469 { switches::kGpuProcess, GpuMain },
[email protected]c955a8d2013-08-06 02:51:15470#endif // !CHROME_MULTIPLE_DLL_BROWSER
[email protected]f573ed6b2012-02-10 15:58:52471 };
472
[email protected]52819472013-11-24 22:49:55473 RegisterMainThreadFactories();
[email protected]d7a2d892013-08-16 07:45:36474
[email protected]f573ed6b2012-02-10 15:58:52475 for (size_t i = 0; i < arraysize(kMainFunctions); ++i) {
476 if (process_type == kMainFunctions[i].name) {
477 if (delegate) {
478 int exit_code = delegate->RunProcess(process_type,
479 main_function_params);
[email protected]e5df69d42012-06-08 00:44:14480#if defined(OS_ANDROID)
481 // In Android's browser process, the negative exit code doesn't mean the
482 // default behavior should be used as the UI message loop is managed by
483 // the Java and the browser process's default behavior is always
484 // overridden.
485 if (process_type.empty())
486 return exit_code;
487#endif
[email protected]f573ed6b2012-02-10 15:58:52488 if (exit_code >= 0)
489 return exit_code;
490 }
491 return kMainFunctions[i].function(main_function_params);
492 }
493 }
494
[email protected]e0825562012-05-10 01:50:47495#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]f573ed6b2012-02-10 15:58:52496 // Zygote startup is special -- see RunZygote comments above
497 // for why we don't use ZygoteMain directly.
498 if (process_type == switches::kZygoteProcess)
499 return RunZygote(main_function_params, delegate);
500#endif
501
502 // If it's a process we don't know about, the embedder should know.
503 if (delegate)
504 return delegate->RunProcess(process_type, main_function_params);
505
506 NOTREACHED() << "Unknown process type: " << process_type;
507 return 1;
508}
509
[email protected]c6681f32012-06-05 14:43:01510class ContentMainRunnerImpl : public ContentMainRunner {
[email protected]f573ed6b2012-02-10 15:58:52511 public:
512 ContentMainRunnerImpl()
513 : is_initialized_(false),
[email protected]dab255412012-02-14 18:38:09514 is_shutdown_(false),
[email protected]91550a62012-06-07 17:26:30515 completed_basic_startup_(false),
[email protected]a88f6362014-03-18 04:25:35516 delegate_(NULL),
517 ui_task_(NULL) {
[email protected]f80131d2012-07-25 22:20:25518#if defined(OS_WIN)
519 memset(&sandbox_info_, 0, sizeof(sandbox_info_));
520#endif
[email protected]f573ed6b2012-02-10 15:58:52521 }
522
dchenge933b3e2014-10-21 11:44:09523 ~ContentMainRunnerImpl() override {
[email protected]f573ed6b2012-02-10 15:58:52524 if (is_initialized_ && !is_shutdown_)
525 Shutdown();
526 }
527
dchenge933b3e2014-10-21 11:44:09528 int Initialize(const ContentMainParams& params) override {
[email protected]a88f6362014-03-18 04:25:35529 ui_task_ = params.ui_task;
530
sky89636c32016-12-13 03:24:33531#if defined(USE_AURA)
532 env_mode_ = params.env_mode;
533#endif
534
erikchenbf11b55a2017-02-10 01:34:48535#if defined(OS_MACOSX) && BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM)
536 base::allocator::InitializeAllocatorShim();
537#endif
cpu3e11a842015-01-27 18:13:45538 base::EnableTerminationOnOutOfMemory();
[email protected]5d90df52014-03-27 04:16:00539#if defined(OS_WIN)
pmonette18d3ed32015-10-16 21:06:06540 base::win::RegisterInvalidParamHandler();
[email protected]75f6dea02014-06-11 12:13:23541 ui::win::CreateATLModuleIfNeeded();
[email protected]f573ed6b2012-02-10 15:58:52542
[email protected]8a820c82014-03-09 18:06:58543 sandbox_info_ = *params.sandbox_info;
[email protected]f573ed6b2012-02-10 15:58:52544#else // !OS_WIN
[email protected]e0825562012-05-10 01:50:47545
[email protected]aa328c72013-05-03 10:55:43546#if defined(OS_ANDROID)
547 // See note at the initialization of ExitManager, below; basically,
548 // only Android builds have the ctor/dtor handlers set up to use
549 // TRACE_EVENT right away.
alexandermontcd6ea3292016-08-12 17:24:07550 TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize");
[email protected]aa328c72013-05-03 10:55:43551#endif // OS_ANDROID
552
rmcilroy3fb07272015-02-24 13:33:04553 base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance();
nedenwang0ca26a72016-08-23 07:34:05554 ALLOW_UNUSED_LOCAL(g_fds);
rmcilroy3fb07272015-02-24 13:33:04555
[email protected]e0825562012-05-10 01:50:47556 // On Android,
557 // - setlocale() is not supported.
558 // - We do not override the signal handlers so that we can get
559 // stack trace when crashing.
560 // - The ipc_fd is passed through the Java service.
561 // Thus, these are all disabled.
jame1f453c2016-03-21 15:51:34562#if !defined(OS_ANDROID)
[email protected]f573ed6b2012-02-10 15:58:52563 // Set C library locale to make sure CommandLine can parse argument values
564 // in correct encoding.
565 setlocale(LC_ALL, "");
[email protected]f573ed6b2012-02-10 15:58:52566
567 SetupSignalHandlers();
rockote8b8da42016-03-02 06:20:23568 g_fds->Set(kMojoIPCChannel,
569 kMojoIPCChannel + base::GlobalDescriptors::kBaseDescriptor);
lawrencewuc4fe8802016-11-30 16:25:02570
571 g_fds->Set(
572 kFieldTrialDescriptor,
573 kFieldTrialDescriptor + base::GlobalDescriptors::kBaseDescriptor);
jame1f453c2016-03-21 15:51:34574#endif // !OS_ANDROID
[email protected]e0825562012-05-10 01:50:47575
[email protected]f573ed6b2012-02-10 15:58:52576#if defined(OS_LINUX) || defined(OS_OPENBSD)
577 g_fds->Set(kCrashDumpSignal,
578 kCrashDumpSignal + base::GlobalDescriptors::kBaseDescriptor);
rmcilroy3fb07272015-02-24 13:33:04579#endif // OS_LINUX || OS_OPENBSD
580
[email protected]f573ed6b2012-02-10 15:58:52581
582#endif // !OS_WIN
583
584 is_initialized_ = true;
[email protected]8a820c82014-03-09 18:06:58585 delegate_ = params.delegate;
[email protected]f573ed6b2012-02-10 15:58:52586
[email protected]d582fbc22012-09-11 10:59:37587 // The exit manager is in charge of calling the dtors of singleton objects.
[email protected]122984a2012-09-13 09:57:11588 // On Android, AtExitManager is set up when library is loaded.
[email protected]aa328c72013-05-03 10:55:43589 // A consequence of this is that you can't use the ctor/dtor-based
590 // TRACE_EVENT methods on Linux or iOS builds till after we set this up.
jame1f453c2016-03-21 15:51:34591#if !defined(OS_ANDROID)
[email protected]a88f6362014-03-18 04:25:35592 if (!ui_task_) {
593 // When running browser tests, don't create a second AtExitManager as that
594 // interfers with shutdown when objects created before ContentMain is
595 // called are destructed when it returns.
596 exit_manager_.reset(new base::AtExitManager);
597 }
jame1f453c2016-03-21 15:51:34598#endif // !OS_ANDROID
[email protected]d582fbc22012-09-11 10:59:37599
jame1f453c2016-03-21 15:51:34600#if defined(OS_MACOSX)
[email protected]f573ed6b2012-02-10 15:58:52601 // We need this pool for all the objects created before we get to the
602 // event loop, but we don't want to leave them hanging around until the
603 // app quits. Each "main" needs to flush this pool right before it goes into
604 // its main event loop to get rid of the cruft.
605 autorelease_pool_.reset(new base::mac::ScopedNSAutoreleasePool());
ccameronc685e64c2015-05-12 07:05:17606 InitializeMac();
[email protected]f573ed6b2012-02-10 15:58:52607#endif
608
jcivellidad0cef2017-02-16 18:38:59609// On Android, the command line is initialized and the FDs set when the
610// library is loaded and we have already started our TRACE_EVENT0.
[email protected]9fc1dd22012-06-13 23:54:43611#if !defined(OS_ANDROID)
[email protected]8a820c82014-03-09 18:06:58612 // argc/argv are ignored on Windows and Android; see command_line.h for
613 // details.
614 int argc = 0;
615 const char** argv = NULL;
616
617#if !defined(OS_WIN)
618 argc = params.argc;
619 argv = params.argv;
620#endif
621
[email protected]479278702014-08-11 20:32:09622 base::CommandLine::Init(argc, argv);
[email protected]8a820c82014-03-09 18:06:58623
jcivellidad0cef2017-02-16 18:38:59624#if defined(OS_POSIX)
625 PopulateFDsFromCommandLine();
626#endif
627
erikwright23af4fa2015-03-11 19:43:26628 base::EnableTerminationOnHeapCorruption();
[email protected]83882d42014-08-01 19:23:09629
yiyaoliu9e6a5ab32015-03-18 18:04:37630 // TODO(yiyaoliu, vadimt): Remove this once crbug.com/453640 is fixed.
631 // Enable profiler recording right after command line is initialized so that
632 // browser startup can be instrumented.
633 if (delegate_ && delegate_->ShouldEnableProfilerRecording())
634 tracked_objects::ScopedTracker::Enable();
635
[email protected]8a820c82014-03-09 18:06:58636 SetProcessTitleFromCommandLine(argv);
pmonette18d3ed32015-10-16 21:06:06637#endif // !OS_ANDROID
[email protected]f573ed6b2012-02-10 15:58:52638
[email protected]be1f51662014-07-29 10:43:08639 int exit_code = 0;
[email protected]8a820c82014-03-09 18:06:58640 if (delegate_ && delegate_->BasicStartupComplete(&exit_code))
[email protected]f573ed6b2012-02-10 15:58:52641 return exit_code;
642
[email protected]dab255412012-02-14 18:38:09643 completed_basic_startup_ = true;
644
[email protected]479278702014-08-11 20:32:09645 const base::CommandLine& command_line =
646 *base::CommandLine::ForCurrentProcess();
[email protected]f573ed6b2012-02-10 15:58:52647 std::string process_type =
[email protected]c6681f32012-06-05 14:43:01648 command_line.GetSwitchValueASCII(switches::kProcessType);
649
[email protected]5d90df52014-03-27 04:16:00650 // Initialize mojo here so that services can be registered.
651 InitializeMojo();
[email protected]5d90df52014-03-27 04:16:00652
anantab1f93132014-09-26 02:20:35653#if defined(OS_WIN)
anantab1f93132014-09-26 02:20:35654 if (command_line.HasSwitch(switches::kDeviceScaleFactor)) {
655 std::string scale_factor_string = command_line.GetSwitchValueASCII(
656 switches::kDeviceScaleFactor);
657 double scale_factor = 0;
pkasting91475b02015-12-17 08:35:24658 if (base::StringToDouble(scale_factor_string, &scale_factor))
robliao18e220e82016-04-19 16:47:12659 display::win::SetDefaultDeviceScaleFactor(scale_factor);
anantab1f93132014-09-26 02:20:35660 }
anantab1f93132014-09-26 02:20:35661#endif
662
[email protected]c6681f32012-06-05 14:43:01663 if (!GetContentClient())
664 SetContentClient(&empty_content_client_);
665 ContentClientInitializer::Set(process_type, delegate_);
[email protected]f573ed6b2012-02-10 15:58:52666
[email protected]c7c1e4d2012-08-22 04:06:06667#if defined(OS_WIN)
668 // Route stdio to parent console (if any) or create one.
669 if (command_line.HasSwitch(switches::kEnableLogging))
jam79dc59a2015-08-17 03:38:16670 base::RouteStdioToConsole(true);
[email protected]c7c1e4d2012-08-22 04:06:06671#endif
672
zhenw79cf61802015-11-20 19:12:48673#if !defined(OS_ANDROID)
[email protected]f573ed6b2012-02-10 15:58:52674 // Enable startup tracing asap to avoid early TRACE_EVENT calls being
zhenw79cf61802015-11-20 19:12:48675 // ignored. For Android, startup tracing is enabled in an even earlier place
676 // content/app/android/library_loader_hooks.cc.
ssid69e84192017-02-16 14:32:47677 // Zygote process does not have file thread and renderer process on Win10
678 // cannot access the file system.
679 // TODO(ssid): Check if other processes can enable startup tracing here.
680 bool can_access_file_system = (process_type != switches::kZygoteProcess &&
681 process_type != switches::kRendererProcess);
682 tracing::EnableStartupTracingIfNeeded(can_access_file_system);
zhenw79cf61802015-11-20 19:12:48683#endif // !OS_ANDROID
zhenw062a94522015-06-22 20:55:28684
georgesak28ad5e62015-04-16 09:25:19685#if defined(OS_WIN)
686 // Enable exporting of events to ETW if requested on the command line.
687 if (command_line.HasSwitch(switches::kTraceExportEventsToETW))
688 base::trace_event::TraceEventETWExport::EnableETWExport();
689#endif // OS_WIN
690
[email protected]aa328c72013-05-03 10:55:43691#if !defined(OS_ANDROID)
692 // Android tracing started at the beginning of the method.
693 // Other OSes have to wait till we get here in order for all the memory
694 // management setup to be completed.
alexandermontcd6ea3292016-08-12 17:24:07695 TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize");
pmonette18d3ed32015-10-16 21:06:06696#endif // !OS_ANDROID
[email protected]f573ed6b2012-02-10 15:58:52697
jame1f453c2016-03-21 15:51:34698#if defined(OS_MACOSX)
[email protected]f573ed6b2012-02-10 15:58:52699 // We need to allocate the IO Ports before the Sandbox is initialized or
[email protected]6c5905b72013-04-03 19:06:51700 // the first instance of PowerMonitor is created.
[email protected]f573ed6b2012-02-10 15:58:52701 // It's important not to allocate the ports for processes which don't
[email protected]6c5905b72013-04-03 19:06:51702 // register with the power monitor - see crbug.com/88867.
[email protected]f573ed6b2012-02-10 15:58:52703 if (process_type.empty() ||
[email protected]8a820c82014-03-09 18:06:58704 (delegate_ &&
705 delegate_->ProcessRegistersWithSystemProcess(process_type))) {
[email protected]9dd90152013-08-02 22:09:13706 base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
[email protected]f573ed6b2012-02-10 15:58:52707 }
708
709 if (!process_type.empty() &&
[email protected]8a820c82014-03-09 18:06:58710 (!delegate_ || delegate_->ShouldSendMachPort(process_type))) {
[email protected]3c2119d2013-04-11 14:27:28711 MachBroker::ChildSendTaskPortToParent();
[email protected]f573ed6b2012-02-10 15:58:52712 }
713#elif defined(OS_WIN)
pmonette18d3ed32015-10-16 21:06:06714 base::win::SetupCRT(command_line);
[email protected]f573ed6b2012-02-10 15:58:52715#endif
716
primianobe9d6fc2016-01-12 22:16:11717 // If we are on a platform where the default allocator is overridden (shim
718 // layer on windows, tcmalloc on Linux Desktop) smoke-tests that the
719 // overriding logic is working correctly. If not causes a hard crash, as its
720 // unexpected absence has security implications.
721 CHECK(base::allocator::IsAllocatorInitialized());
722
[email protected]f573ed6b2012-02-10 15:58:52723#if defined(OS_POSIX)
724 if (!process_type.empty()) {
725 // When you hit Ctrl-C in a terminal running the browser
726 // process, a SIGINT is delivered to the entire process group.
727 // When debugging the browser process via gdb, gdb catches the
728 // SIGINT for the browser process (and dumps you back to the gdb
729 // console) but doesn't for the child processes, killing them.
730 // The fix is to have child processes ignore SIGINT; they'll die
731 // on their own when the browser process goes away.
732 //
733 // Note that we *can't* rely on BeingDebugged to catch this case because
734 // we are the child process, which is not being debugged.
735 // TODO(evanm): move this to some shared subprocess-init function.
736 if (!base::debug::BeingDebugged())
737 signal(SIGINT, SIG_IGN);
738 }
739#endif
740
davidben71f35ff2015-04-17 20:54:48741#if defined(USE_NSS_CERTS)
[email protected]f573ed6b2012-02-10 15:58:52742 crypto::EarlySetupForNSSInit();
743#endif
744
745 ui::RegisterPathProvider();
[email protected]c6681f32012-06-05 14:43:01746 RegisterPathProvider();
747 RegisterContentSchemes(true);
[email protected]f573ed6b2012-02-10 15:58:52748
nedenwang0ca26a72016-08-23 07:34:05749#if defined(OS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
rmcilroy3fb07272015-02-24 13:33:04750 int icudata_fd = g_fds->MaybeGet(kAndroidICUDataDescriptor);
mkosiba3c766cc2015-01-09 13:10:22751 if (icudata_fd != -1) {
rmcilroy3fb07272015-02-24 13:33:04752 auto icudata_region = g_fds->GetRegion(kAndroidICUDataDescriptor);
mkosiba3c766cc2015-01-09 13:10:22753 CHECK(base::i18n::InitializeICUWithFileDescriptor(icudata_fd,
754 icudata_region));
755 } else {
[email protected]09560f7f2014-06-10 18:40:28756 CHECK(base::i18n::InitializeICU());
mkosiba3c766cc2015-01-09 13:10:22757 }
rmcilroy3fb07272015-02-24 13:33:04758#else
759 CHECK(base::i18n::InitializeICU());
nedenwang0ca26a72016-08-23 07:34:05760#endif // OS_ANDROID && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
baixo3a3c88a2014-10-28 11:52:21761
oth575f7fb52015-05-08 17:35:00762 base::StatisticsRecorder::Initialize();
763
jcivelli15ffa462017-02-09 18:01:30764 InitializeV8IfNeeded(command_line, process_type);
[email protected]f573ed6b2012-02-10 15:58:52765
sadrulf6fb2a72017-02-08 17:59:28766#if !defined(OFFICIAL_BUILD)
767#if defined(OS_WIN)
768 bool should_enable_stack_dump = !process_type.empty();
769#else
770 bool should_enable_stack_dump = true;
771#endif
772 // Print stack traces to stderr when crashes occur. This opens up security
773 // holes so it should never be enabled for official builds. This needs to
774 // happen before crash reporting is initialized (which for chrome happens in
775 // the call to PreSandboxStartup() on the delegate below), because otherwise
776 // this would interfere with signal handlers used by crash reporting.
777 if (should_enable_stack_dump && !command_line.HasSwitch(
778 switches::kDisableInProcessStackTraces)) {
779 base::debug::EnableInProcessStackDumping();
780 }
781#endif // !defined(OFFICIAL_BUILD)
782
[email protected]8a820c82014-03-09 18:06:58783 if (delegate_)
784 delegate_->PreSandboxStartup();
[email protected]f573ed6b2012-02-10 15:58:52785
786 if (!process_type.empty())
sadrulf6fb2a72017-02-08 17:59:28787 CommonSubprocessInit();
[email protected]f573ed6b2012-02-10 15:58:52788
789#if defined(OS_WIN)
[email protected]8a820c82014-03-09 18:06:58790 CHECK(InitializeSandbox(params.sandbox_info));
jame1f453c2016-03-21 15:51:34791#elif defined(OS_MACOSX)
[email protected]f573ed6b2012-02-10 15:58:52792 if (process_type == switches::kRendererProcess ||
793 process_type == switches::kPpapiPluginProcess ||
[email protected]8a820c82014-03-09 18:06:58794 (delegate_ && delegate_->DelaySandboxInitialization(process_type))) {
[email protected]f573ed6b2012-02-10 15:58:52795 // On OS X the renderer sandbox needs to be initialized later in the
796 // startup sequence in RendererMainPlatformDelegate::EnableSandbox().
797 } else {
[email protected]c6681f32012-06-05 14:43:01798 CHECK(InitializeSandbox());
[email protected]f573ed6b2012-02-10 15:58:52799 }
800#endif
801
[email protected]8a820c82014-03-09 18:06:58802 if (delegate_)
803 delegate_->SandboxInitialized(process_type);
[email protected]f573ed6b2012-02-10 15:58:52804
805 // Return -1 to indicate no early termination.
806 return -1;
807 }
808
dchenge933b3e2014-10-21 11:44:09809 int Run() override {
[email protected]f573ed6b2012-02-10 15:58:52810 DCHECK(is_initialized_);
811 DCHECK(!is_shutdown_);
[email protected]479278702014-08-11 20:32:09812 const base::CommandLine& command_line =
813 *base::CommandLine::ForCurrentProcess();
[email protected]f573ed6b2012-02-10 15:58:52814 std::string process_type =
[email protected]479278702014-08-11 20:32:09815 command_line.GetSwitchValueASCII(switches::kProcessType);
[email protected]f573ed6b2012-02-10 15:58:52816
erikchen55edbff2016-05-03 23:53:17817 // Run this logic on all child processes. Zygotes will run this at a later
818 // point in time when the command line has been updated.
819 std::unique_ptr<base::FieldTrialList> field_trial_list;
820 if (!process_type.empty() && process_type != switches::kZygoteProcess)
821 InitializeFieldTrialAndFeatureList(&field_trial_list);
822
bcwhited723c252016-03-16 17:25:41823 base::HistogramBase::EnableActivityReportHistogram(process_type);
824
[email protected]c6681f32012-06-05 14:43:01825 MainFunctionParams main_params(command_line);
[email protected]a88f6362014-03-18 04:25:35826 main_params.ui_task = ui_task_;
[email protected]f573ed6b2012-02-10 15:58:52827#if defined(OS_WIN)
828 main_params.sandbox_info = &sandbox_info_;
829#elif defined(OS_MACOSX)
830 main_params.autorelease_pool = autorelease_pool_.get();
831#endif
sky89636c32016-12-13 03:24:33832#if defined(USE_AURA)
833 main_params.env_mode = env_mode_;
834#endif
[email protected]f573ed6b2012-02-10 15:58:52835
836 return RunNamedProcessTypeMain(process_type, main_params, delegate_);
837 }
838
dchenge933b3e2014-10-21 11:44:09839 void Shutdown() override {
[email protected]f573ed6b2012-02-10 15:58:52840 DCHECK(is_initialized_);
841 DCHECK(!is_shutdown_);
[email protected]dab255412012-02-14 18:38:09842
843 if (completed_basic_startup_ && delegate_) {
[email protected]479278702014-08-11 20:32:09844 const base::CommandLine& command_line =
845 *base::CommandLine::ForCurrentProcess();
[email protected]dab255412012-02-14 18:38:09846 std::string process_type =
[email protected]f573ed6b2012-02-10 15:58:52847 command_line.GetSwitchValueASCII(switches::kProcessType);
848
[email protected]f573ed6b2012-02-10 15:58:52849 delegate_->ProcessExiting(process_type);
[email protected]dab255412012-02-14 18:38:09850 }
[email protected]f573ed6b2012-02-10 15:58:52851
852#if defined(OS_WIN)
853#ifdef _CRTDBG_MAP_ALLOC
854 _CrtDumpMemoryLeaks();
855#endif // _CRTDBG_MAP_ALLOC
[email protected]f573ed6b2012-02-10 15:58:52856#endif // OS_WIN
857
jame1f453c2016-03-21 15:51:34858#if defined(OS_MACOSX)
[email protected]f573ed6b2012-02-10 15:58:52859 autorelease_pool_.reset(NULL);
860#endif
861
862 exit_manager_.reset(NULL);
863
864 delegate_ = NULL;
865 is_shutdown_ = true;
866 }
867
[email protected]c6681f32012-06-05 14:43:01868 private:
[email protected]f573ed6b2012-02-10 15:58:52869 // True if the runner has been initialized.
870 bool is_initialized_;
871
872 // True if the runner has been shut down.
873 bool is_shutdown_;
874
[email protected]dab255412012-02-14 18:38:09875 // True if basic startup was completed.
876 bool completed_basic_startup_;
877
[email protected]c6681f32012-06-05 14:43:01878 // Used if the embedder doesn't set one.
879 ContentClient empty_content_client_;
880
[email protected]f573ed6b2012-02-10 15:58:52881 // The delegate will outlive this object.
[email protected]c6681f32012-06-05 14:43:01882 ContentMainDelegate* delegate_;
[email protected]f573ed6b2012-02-10 15:58:52883
dcheng6003e0b2016-04-09 18:42:34884 std::unique_ptr<base::AtExitManager> exit_manager_;
[email protected]f573ed6b2012-02-10 15:58:52885#if defined(OS_WIN)
886 sandbox::SandboxInterfaceInfo sandbox_info_;
887#elif defined(OS_MACOSX)
dcheng6003e0b2016-04-09 18:42:34888 std::unique_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool_;
[email protected]f573ed6b2012-02-10 15:58:52889#endif
890
[email protected]a88f6362014-03-18 04:25:35891 base::Closure* ui_task_;
892
sky89636c32016-12-13 03:24:33893#if defined(USE_AURA)
894 aura::Env::Mode env_mode_ = aura::Env::Mode::LOCAL;
895#endif
896
[email protected]f573ed6b2012-02-10 15:58:52897 DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
898};
899
[email protected]f573ed6b2012-02-10 15:58:52900// static
901ContentMainRunner* ContentMainRunner::Create() {
902 return new ContentMainRunnerImpl();
903}
904
905} // namespace content