| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/app/content_main.h" | 5 #include "content/app/content_main.h" |
| 6 | 6 |
| 7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
| 8 #include "base/base_switches.h" | |
| 9 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 10 #include "base/debug/debugger.h" | 9 #include "base/debug/debugger.h" |
| 11 #include "base/i18n/icu_util.h" | 10 #include "base/i18n/icu_util.h" |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 13 #include "base/mac/scoped_nsautorelease_pool.h" | 12 #include "base/mac/scoped_nsautorelease_pool.h" |
| 14 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/metrics/stats_table.h" | 14 #include "base/metrics/stats_table.h" |
| 16 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 17 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
| 18 #include "base/string_number_conversions.h" | 17 #include "base/string_number_conversions.h" |
| 19 #include "content/app/content_main_delegate.h" | 18 #include "content/app/content_main_delegate.h" |
| 19 #include "content/app/startup_helper_win.h" |
| 20 #include "content/common/content_constants.h" | 20 #include "content/common/content_constants.h" |
| 21 #include "content/common/content_paths.h" | 21 #include "content/common/content_paths.h" |
| 22 #include "content/common/content_switches.h" | 22 #include "content/common/content_switches.h" |
| 23 #include "content/common/main_function_params.h" | 23 #include "content/common/main_function_params.h" |
| 24 #include "content/common/sandbox_init_wrapper.h" | 24 #include "content/common/sandbox_init_wrapper.h" |
| 25 #include "content/common/set_process_title.h" | 25 #include "content/common/set_process_title.h" |
| 26 #include "crypto/nss_util.h" | 26 #include "crypto/nss_util.h" |
| 27 #include "ipc/ipc_switches.h" | 27 #include "ipc/ipc_switches.h" |
| 28 #include "ui/base/ui_base_switches.h" | 28 #include "ui/base/ui_base_switches.h" |
| 29 #include "ui/base/ui_base_paths.h" | 29 #include "ui/base/ui_base_paths.h" |
| 30 | 30 |
| 31 #if defined(OS_WIN) | 31 #if defined(OS_WIN) |
| 32 #include <atlbase.h> | 32 #include <atlbase.h> |
| 33 #include <atlapp.h> | 33 #include <atlapp.h> |
| 34 #include <new.h> | |
| 35 #include <malloc.h> | 34 #include <malloc.h> |
| 36 #elif defined(OS_MACOSX) | 35 #elif defined(OS_MACOSX) |
| 37 #include "base/mach_ipc_mac.h" | 36 #include "base/mach_ipc_mac.h" |
| 38 #include "base/system_monitor/system_monitor.h" | 37 #include "base/system_monitor/system_monitor.h" |
| 39 #include "content/browser/mach_broker_mac.h" | 38 #include "content/browser/mach_broker_mac.h" |
| 40 #endif // OS_WIN | 39 #endif // OS_WIN |
| 41 | 40 |
| 42 #if defined(OS_POSIX) | 41 #if defined(OS_POSIX) |
| 43 #include <signal.h> | 42 #include <signal.h> |
| 44 | 43 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 69 extern int ZygoteMain(const MainFunctionParams&, | 68 extern int ZygoteMain(const MainFunctionParams&, |
| 70 ZygoteForkDelegate* forkdelegate); | 69 ZygoteForkDelegate* forkdelegate); |
| 71 #endif | 70 #endif |
| 72 | 71 |
| 73 namespace { | 72 namespace { |
| 74 | 73 |
| 75 #if defined(OS_WIN) | 74 #if defined(OS_WIN) |
| 76 | 75 |
| 77 static CAppModule _Module; | 76 static CAppModule _Module; |
| 78 | 77 |
| 79 #pragma optimize("", off) | |
| 80 // Handlers for invalid parameter and pure call. They generate a breakpoint to | |
| 81 // tell breakpad that it needs to dump the process. | |
| 82 void InvalidParameter(const wchar_t* expression, const wchar_t* function, | |
| 83 const wchar_t* file, unsigned int line, | |
| 84 uintptr_t reserved) { | |
| 85 __debugbreak(); | |
| 86 _exit(1); | |
| 87 } | |
| 88 | |
| 89 void PureCall() { | |
| 90 __debugbreak(); | |
| 91 _exit(1); | |
| 92 } | |
| 93 #pragma optimize("", on) | |
| 94 | |
| 95 // Register the invalid param handler and pure call handler to be able to | |
| 96 // notify breakpad when it happens. | |
| 97 void RegisterInvalidParamHandler() { | |
| 98 _set_invalid_parameter_handler(InvalidParameter); | |
| 99 _set_purecall_handler(PureCall); | |
| 100 // Also enable the new handler for malloc() based failures. | |
| 101 _set_new_mode(1); | |
| 102 } | |
| 103 | |
| 104 #elif defined(OS_MACOSX) | 78 #elif defined(OS_MACOSX) |
| 105 | 79 |
| 106 // Completes the Mach IPC handshake by sending this process' task port to the | 80 // Completes the Mach IPC handshake by sending this process' task port to the |
| 107 // parent process. The parent is listening on the Mach port given by | 81 // parent process. The parent is listening on the Mach port given by |
| 108 // |GetMachPortName()|. The task port is used by the parent to get CPU/memory | 82 // |GetMachPortName()|. The task port is used by the parent to get CPU/memory |
| 109 // stats to display in the task manager. | 83 // stats to display in the task manager. |
| 110 void SendTaskPortToParentProcess() { | 84 void SendTaskPortToParentProcess() { |
| 111 const mach_msg_timeout_t kTimeoutMs = 100; | 85 const mach_msg_timeout_t kTimeoutMs = 100; |
| 112 const int32_t kMessageId = 0; | 86 const int32_t kMessageId = 0; |
| 113 std::string mach_port_name = MachBroker::GetMachPortName(); | 87 std::string mach_port_name = MachBroker::GetMachPortName(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 for (unsigned i = 0; i < arraysize(signals_to_reset); i++) { | 121 for (unsigned i = 0; i < arraysize(signals_to_reset); i++) { |
| 148 CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL)); | 122 CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL)); |
| 149 } | 123 } |
| 150 | 124 |
| 151 // Always ignore SIGPIPE. We check the return value of write(). | 125 // Always ignore SIGPIPE. We check the return value of write(). |
| 152 CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); | 126 CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR); |
| 153 } | 127 } |
| 154 | 128 |
| 155 #endif // OS_POSIX | 129 #endif // OS_POSIX |
| 156 | 130 |
| 157 void SetupCRT(const CommandLine& command_line) { | |
| 158 #if defined(OS_WIN) | |
| 159 #if defined(_CRTDBG_MAP_ALLOC) | |
| 160 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); | |
| 161 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); | |
| 162 #else | |
| 163 if (!command_line.HasSwitch(switches::kDisableBreakpad)) { | |
| 164 _CrtSetReportMode(_CRT_ASSERT, 0); | |
| 165 } | |
| 166 #endif | |
| 167 #endif | |
| 168 } | |
| 169 | |
| 170 void CommonSubprocessInit(const std::string& process_type) { | 131 void CommonSubprocessInit(const std::string& process_type) { |
| 171 #if defined(OS_WIN) | 132 #if defined(OS_WIN) |
| 172 // HACK: Let Windows know that we have started. This is needed to suppress | 133 // HACK: Let Windows know that we have started. This is needed to suppress |
| 173 // the IDC_APPSTARTING cursor from being displayed for a prolonged period | 134 // the IDC_APPSTARTING cursor from being displayed for a prolonged period |
| 174 // while a subprocess is starting. | 135 // while a subprocess is starting. |
| 175 PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0); | 136 PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0); |
| 176 MSG msg; | 137 MSG msg; |
| 177 PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); | 138 PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); |
| 178 #endif | 139 #endif |
| 179 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 140 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 namespace content { | 273 namespace content { |
| 313 | 274 |
| 314 #if defined(OS_WIN) | 275 #if defined(OS_WIN) |
| 315 int ContentMain(HINSTANCE instance, | 276 int ContentMain(HINSTANCE instance, |
| 316 sandbox::SandboxInterfaceInfo* sandbox_info, | 277 sandbox::SandboxInterfaceInfo* sandbox_info, |
| 317 ContentMainDelegate* delegate) { | 278 ContentMainDelegate* delegate) { |
| 318 // argc/argv are ignored on Windows; see command_line.h for details. | 279 // argc/argv are ignored on Windows; see command_line.h for details. |
| 319 int argc = 0; | 280 int argc = 0; |
| 320 char** argv = NULL; | 281 char** argv = NULL; |
| 321 | 282 |
| 322 RegisterInvalidParamHandler(); | 283 content::RegisterInvalidParamHandler(); |
| 323 _Module.Init(NULL, static_cast<HINSTANCE>(instance)); | 284 _Module.Init(NULL, static_cast<HINSTANCE>(instance)); |
| 324 #else | 285 #else |
| 325 int ContentMain(int argc, | 286 int ContentMain(int argc, |
| 326 char** argv, | 287 char** argv, |
| 327 ContentMainDelegate* delegate) { | 288 ContentMainDelegate* delegate) { |
| 328 // NOTE(willchan): One might ask why this call is done here rather than in | 289 // NOTE(willchan): One might ask why this call is done here rather than in |
| 329 // process_util_linux.cc with the definition of | 290 // process_util_linux.cc with the definition of |
| 330 // EnableTerminationOnOutOfMemory(). That's because base shouldn't have a | 291 // EnableTerminationOnOutOfMemory(). That's because base shouldn't have a |
| 331 // dependency on TCMalloc. Really, we ought to have our allocator shim code | 292 // dependency on TCMalloc. Really, we ought to have our allocator shim code |
| 332 // implement this EnableTerminationOnOutOfMemory() function. Whateverz. This | 293 // implement this EnableTerminationOnOutOfMemory() function. Whateverz. This |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 process_type == switches::kUtilityProcess || | 346 process_type == switches::kUtilityProcess || |
| 386 process_type == switches::kWorkerProcess || | 347 process_type == switches::kWorkerProcess || |
| 387 (delegate && delegate->ProcessRegistersWithSystemProcess(process_type))) { | 348 (delegate && delegate->ProcessRegistersWithSystemProcess(process_type))) { |
| 388 base::SystemMonitor::AllocateSystemIOPorts(); | 349 base::SystemMonitor::AllocateSystemIOPorts(); |
| 389 } | 350 } |
| 390 | 351 |
| 391 if (!process_type.empty() && | 352 if (!process_type.empty() && |
| 392 (!delegate || delegate->ShouldSendMachPort(process_type))) { | 353 (!delegate || delegate->ShouldSendMachPort(process_type))) { |
| 393 SendTaskPortToParentProcess(); | 354 SendTaskPortToParentProcess(); |
| 394 } | 355 } |
| 356 #elif defined(OS_WIN) |
| 357 content::SetupCRT(command_line); |
| 395 #endif | 358 #endif |
| 396 | 359 |
| 397 #if defined(OS_POSIX) | 360 #if defined(OS_POSIX) |
| 398 if (!process_type.empty()) { | 361 if (!process_type.empty()) { |
| 399 // When you hit Ctrl-C in a terminal running the browser | 362 // When you hit Ctrl-C in a terminal running the browser |
| 400 // process, a SIGINT is delivered to the entire process group. | 363 // process, a SIGINT is delivered to the entire process group. |
| 401 // When debugging the browser process via gdb, gdb catches the | 364 // When debugging the browser process via gdb, gdb catches the |
| 402 // SIGINT for the browser process (and dumps you back to the gdb | 365 // SIGINT for the browser process (and dumps you back to the gdb |
| 403 // console) but doesn't for the child processes, killing them. | 366 // console) but doesn't for the child processes, killing them. |
| 404 // The fix is to have child processes ignore SIGINT; they'll die | 367 // The fix is to have child processes ignore SIGINT; they'll die |
| 405 // on their own when the browser process goes away. | 368 // on their own when the browser process goes away. |
| 406 // | 369 // |
| 407 // Note that we *can't* rely on BeingDebugged to catch this case because we | 370 // Note that we *can't* rely on BeingDebugged to catch this case because we |
| 408 // are the child process, which is not being debugged. | 371 // are the child process, which is not being debugged. |
| 409 // TODO(evanm): move this to some shared subprocess-init function. | 372 // TODO(evanm): move this to some shared subprocess-init function. |
| 410 if (!base::debug::BeingDebugged()) | 373 if (!base::debug::BeingDebugged()) |
| 411 signal(SIGINT, SIG_IGN); | 374 signal(SIGINT, SIG_IGN); |
| 412 } | 375 } |
| 413 #endif | 376 #endif |
| 414 | 377 |
| 415 SetupCRT(command_line); | |
| 416 | |
| 417 #if defined(USE_NSS) | 378 #if defined(USE_NSS) |
| 418 crypto::EarlySetupForNSSInit(); | 379 crypto::EarlySetupForNSSInit(); |
| 419 #endif | 380 #endif |
| 420 | 381 |
| 421 ui::RegisterPathProvider(); | 382 ui::RegisterPathProvider(); |
| 422 content::RegisterPathProvider(); | 383 content::RegisterPathProvider(); |
| 423 | 384 |
| 424 CHECK(icu_util::Initialize()); | 385 CHECK(icu_util::Initialize()); |
| 425 | 386 |
| 426 base::ProcessId browser_pid = base::GetCurrentProcId(); | 387 base::ProcessId browser_pid = base::GetCurrentProcId(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 _CrtDumpMemoryLeaks(); | 449 _CrtDumpMemoryLeaks(); |
| 489 #endif // _CRTDBG_MAP_ALLOC | 450 #endif // _CRTDBG_MAP_ALLOC |
| 490 | 451 |
| 491 _Module.Term(); | 452 _Module.Term(); |
| 492 #endif // OS_WIN | 453 #endif // OS_WIN |
| 493 | 454 |
| 494 return exit_code; | 455 return exit_code; |
| 495 } | 456 } |
| 496 | 457 |
| 497 } // namespace content | 458 } // namespace content |
| OLD | NEW |