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 |