| 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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 break; | 186 break; |
| 187 } | 187 } |
| 188 DPLOG(ERROR) << "Error waiting for process " << process_id; | 188 DPLOG(ERROR) << "Error waiting for process " << process_id; |
| 189 } | 189 } |
| 190 | 190 |
| 191 usleep(sleep_ms * 1000); | 191 usleep(sleep_ms * 1000); |
| 192 if (sleep_ms < kMaxSleepMs) | 192 if (sleep_ms < kMaxSleepMs) |
| 193 sleep_ms *= 2; | 193 sleep_ms *= 2; |
| 194 } | 194 } |
| 195 | 195 |
| 196 // If we're waiting and the child hasn't died by now, force it |
| 197 // with a SIGKILL. |
| 196 if (!exited) | 198 if (!exited) |
| 197 result = kill(process_id, SIGKILL) == 0; | 199 result = kill(process_id, SIGKILL) == 0; |
| 198 } | 200 } |
| 199 | 201 |
| 200 if (!result) | 202 if (!result) |
| 201 DPLOG(ERROR) << "Unable to terminate process " << process_id; | 203 DPLOG(ERROR) << "Unable to terminate process " << process_id; |
| 202 | 204 |
| 203 return result; | 205 return result; |
| 204 } | 206 } |
| 205 | 207 |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 success &= (signal(SIGSYS, &StackDumpSignalHandler) != SIG_ERR); | 581 success &= (signal(SIGSYS, &StackDumpSignalHandler) != SIG_ERR); |
| 580 | 582 |
| 581 return success; | 583 return success; |
| 582 } | 584 } |
| 583 | 585 |
| 584 void RaiseProcessToHighPriority() { | 586 void RaiseProcessToHighPriority() { |
| 585 // On POSIX, we don't actually do anything here. We could try to nice() or | 587 // On POSIX, we don't actually do anything here. We could try to nice() or |
| 586 // setpriority() or sched_getscheduler, but these all require extra rights. | 588 // setpriority() or sched_getscheduler, but these all require extra rights. |
| 587 } | 589 } |
| 588 | 590 |
| 589 bool DidProcessCrash(bool* child_exited, ProcessHandle handle) { | 591 TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { |
| 590 int status; | 592 int status = 0; |
| 591 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG)); | 593 const pid_t result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG)); |
| 592 if (result == -1) { | 594 if (result == -1) { |
| 593 PLOG(ERROR) << "waitpid(" << handle << ")"; | 595 PLOG(ERROR) << "waitpid(" << handle << ")"; |
| 594 if (child_exited) | 596 if (exit_code) |
| 595 *child_exited = false; | 597 *exit_code = 0; |
| 596 return false; | 598 return TERMINATION_STATUS_NORMAL_TERMINATION; |
| 597 } else if (result == 0) { | 599 } else if (result == 0) { |
| 598 // the child hasn't exited yet. | 600 // the child hasn't exited yet. |
| 599 if (child_exited) | 601 if (exit_code) |
| 600 *child_exited = false; | 602 *exit_code = 0; |
| 601 return false; | 603 return TERMINATION_STATUS_STILL_RUNNING; |
| 602 } | 604 } |
| 603 | 605 |
| 604 if (child_exited) | 606 if (exit_code) |
| 605 *child_exited = true; | 607 *exit_code = status; |
| 606 | 608 |
| 607 if (WIFSIGNALED(status)) { | 609 if (WIFSIGNALED(status)) { |
| 608 switch (WTERMSIG(status)) { | 610 switch (WTERMSIG(status)) { |
| 611 case SIGABRT: |
| 612 case SIGBUS: |
| 613 case SIGFPE: |
| 614 case SIGILL: |
| 609 case SIGSEGV: | 615 case SIGSEGV: |
| 610 case SIGILL: | 616 return TERMINATION_STATUS_PROCESS_CRASHED; |
| 611 case SIGABRT: | 617 case SIGINT: |
| 612 case SIGFPE: | 618 case SIGKILL: |
| 613 return true; | 619 case SIGTERM: |
| 620 return TERMINATION_STATUS_PROCESS_WAS_KILLED; |
| 614 default: | 621 default: |
| 615 return false; | 622 break; |
| 616 } | 623 } |
| 617 } | 624 } |
| 618 | 625 |
| 619 if (WIFEXITED(status)) | 626 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) |
| 620 return WEXITSTATUS(status) != 0; | 627 return TERMINATION_STATUS_ABNORMAL_TERMINATION; |
| 621 | 628 |
| 622 return false; | 629 return TERMINATION_STATUS_NORMAL_TERMINATION; |
| 623 } | 630 } |
| 624 | 631 |
| 625 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { | 632 bool WaitForExitCode(ProcessHandle handle, int* exit_code) { |
| 626 int status; | 633 int status; |
| 627 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { | 634 if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) { |
| 628 NOTREACHED(); | 635 NOTREACHED(); |
| 629 return false; | 636 return false; |
| 630 } | 637 } |
| 631 | 638 |
| 632 if (WIFEXITED(status)) { | 639 if (WIFEXITED(status)) { |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 const ProcessFilter* filter) { | 854 const ProcessFilter* filter) { |
| 848 bool exited_cleanly = | 855 bool exited_cleanly = |
| 849 WaitForProcessesToExit(executable_name, wait_milliseconds, | 856 WaitForProcessesToExit(executable_name, wait_milliseconds, |
| 850 filter); | 857 filter); |
| 851 if (!exited_cleanly) | 858 if (!exited_cleanly) |
| 852 KillProcesses(executable_name, exit_code, filter); | 859 KillProcesses(executable_name, exit_code, filter); |
| 853 return exited_cleanly; | 860 return exited_cleanly; |
| 854 } | 861 } |
| 855 | 862 |
| 856 } // namespace base | 863 } // namespace base |
| OLD | NEW |