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