| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <dirent.h> | 5 #include <dirent.h> |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <signal.h> | 8 #include <signal.h> |
| 9 #include <stdlib.h> | 9 #include <stdlib.h> |
| 10 #include <sys/resource.h> | 10 #include <sys/resource.h> |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 102 |
| 103 return status; | 103 return status; |
| 104 } | 104 } |
| 105 | 105 |
| 106 void StackDumpSignalHandler(int signal) { | 106 void StackDumpSignalHandler(int signal) { |
| 107 LOG(ERROR) << "Received signal " << signal; | 107 LOG(ERROR) << "Received signal " << signal; |
| 108 StackTrace().PrintBacktrace(); | 108 StackTrace().PrintBacktrace(); |
| 109 _exit(1); | 109 _exit(1); |
| 110 } | 110 } |
| 111 | 111 |
| 112 void ResetChildSignalHandlersToDefaults() { |
| 113 // The previous signal handlers are likely to be meaningless in the child's |
| 114 // context so we reset them to the defaults for now. http://crbug.com/44953 |
| 115 // These signal handlers are setup in browser_main.cc:BrowserMain |
| 116 signal(SIGTERM, SIG_DFL); |
| 117 signal(SIGHUP, SIG_DFL); |
| 118 signal(SIGINT, SIG_DFL); |
| 119 } |
| 120 |
| 112 } // anonymous namespace | 121 } // anonymous namespace |
| 113 | 122 |
| 114 ProcessId GetCurrentProcId() { | 123 ProcessId GetCurrentProcId() { |
| 115 return getpid(); | 124 return getpid(); |
| 116 } | 125 } |
| 117 | 126 |
| 118 ProcessHandle GetCurrentProcessHandle() { | 127 ProcessHandle GetCurrentProcessHandle() { |
| 119 return GetCurrentProcId(); | 128 return GetCurrentProcId(); |
| 120 } | 129 } |
| 121 | 130 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 | 325 |
| 317 // Error handling philosophy: If Mach IPC fails, don't touch |child_task| but | 326 // Error handling philosophy: If Mach IPC fails, don't touch |child_task| but |
| 318 // return a valid pid. If IPC fails in the child, the parent will have to wait | 327 // return a valid pid. If IPC fails in the child, the parent will have to wait |
| 319 // until kTimeoutMs is over. This is not optimal, but I've never seen it | 328 // until kTimeoutMs is over. This is not optimal, but I've never seen it |
| 320 // happen, and stuff should still mostly work. | 329 // happen, and stuff should still mostly work. |
| 321 pid_t pid = fork(); | 330 pid_t pid = fork(); |
| 322 switch (pid) { | 331 switch (pid) { |
| 323 case -1: | 332 case -1: |
| 324 return pid; | 333 return pid; |
| 325 case 0: { // child | 334 case 0: { // child |
| 335 // Must reset signal handlers before doing any mach IPC, as the mach IPC |
| 336 // calls can potentially hang forever. |
| 337 ResetChildSignalHandlersToDefaults(); |
| 326 MachSendMessage child_message(/* id= */0); | 338 MachSendMessage child_message(/* id= */0); |
| 327 if (!child_message.AddDescriptor(mach_task_self())) { | 339 if (!child_message.AddDescriptor(mach_task_self())) { |
| 328 LOG(ERROR) << "child AddDescriptor(mach_task_self()) failed."; | 340 LOG(ERROR) << "child AddDescriptor(mach_task_self()) failed."; |
| 329 return pid; | 341 return pid; |
| 330 } | 342 } |
| 331 | 343 |
| 332 MachPortSender child_sender(mach_connection_name.c_str()); | 344 MachPortSender child_sender(mach_connection_name.c_str()); |
| 333 err = child_sender.SendMessage(child_message, kTimeoutMs); | 345 err = child_sender.SendMessage(child_message, kTimeoutMs); |
| 334 if (err != KERN_SUCCESS) { | 346 if (err != KERN_SUCCESS) { |
| 335 LOG(ERROR) << "child SendMessage() failed: " << MachErrorCode(err); | 347 LOG(ERROR) << "child SendMessage() failed: " << MachErrorCode(err); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 #endif | 534 #endif |
| 523 if (pid < 0) | 535 if (pid < 0) |
| 524 return false; | 536 return false; |
| 525 | 537 |
| 526 if (pid == 0) { | 538 if (pid == 0) { |
| 527 // Child process | 539 // Child process |
| 528 #if defined(OS_MACOSX) | 540 #if defined(OS_MACOSX) |
| 529 RestoreDefaultExceptionHandler(); | 541 RestoreDefaultExceptionHandler(); |
| 530 #endif | 542 #endif |
| 531 | 543 |
| 532 // The previous signal handlers are likely to be meaningless in the child's | 544 // On mac, the signal handlers are reset in |fork_and_get_task()|. |
| 533 // context so we reset them to the defaults for now. http://crbug.com/44953 | 545 #if !defined(OS_MACOSX) |
| 534 // These signal handlers are setup in browser_main.cc:BrowserMain | 546 ResetChildSignalHandlersToDefaults(); |
| 535 signal(SIGTERM, SIG_DFL); | 547 #endif |
| 536 signal(SIGHUP, SIG_DFL); | |
| 537 signal(SIGINT, SIG_DFL); | |
| 538 | 548 |
| 539 #if 0 | 549 #if 0 |
| 540 // When debugging it can be helpful to check that we really aren't making | 550 // When debugging it can be helpful to check that we really aren't making |
| 541 // any hidden calls to malloc. | 551 // any hidden calls to malloc. |
| 542 void *malloc_thunk = | 552 void *malloc_thunk = |
| 543 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); | 553 reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095); |
| 544 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); | 554 mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC); |
| 545 memset(reinterpret_cast<void*>(malloc), 0xff, 8); | 555 memset(reinterpret_cast<void*>(malloc), 0xff, 8); |
| 546 #endif | 556 #endif |
| 547 | 557 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 const ProcessFilter* filter) { | 910 const ProcessFilter* filter) { |
| 901 bool exited_cleanly = | 911 bool exited_cleanly = |
| 902 WaitForProcessesToExit(executable_name, wait_milliseconds, | 912 WaitForProcessesToExit(executable_name, wait_milliseconds, |
| 903 filter); | 913 filter); |
| 904 if (!exited_cleanly) | 914 if (!exited_cleanly) |
| 905 KillProcesses(executable_name, exit_code, filter); | 915 KillProcesses(executable_name, exit_code, filter); |
| 906 return exited_cleanly; | 916 return exited_cleanly; |
| 907 } | 917 } |
| 908 | 918 |
| 909 } // namespace base | 919 } // namespace base |
| OLD | NEW |