blob: 63055a83009bcd8ff7562c661b3edad4f89a2ff1 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]307af212013-07-10 18:36:092// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/process/kill.h"
6
Wezc18a57c2018-04-02 20:20:147#include <algorithm>
8
[email protected]307af212013-07-10 18:36:099#include <windows.h>
avibeced7c2015-12-24 06:47:5910#include <io.h>
11#include <stdint.h>
[email protected]307af212013-07-10 18:36:0912
[email protected]307af212013-07-10 18:36:0913#include "base/logging.h"
Hans Wennborgafeb3902020-06-17 14:42:2914#include "base/notreached.h"
wfhfa40c2722016-07-26 01:12:2815#include "base/process/memory.h"
[email protected]307af212013-07-10 18:36:0916#include "base/process/process_iterator.h"
[email protected]307af212013-07-10 18:36:0917
18namespace base {
19
[email protected]307af212013-07-10 18:36:0920TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
Wez05c2c682017-08-17 16:20:1121 DCHECK(exit_code);
22
[email protected]307af212013-07-10 18:36:0923 DWORD tmp_exit_code = 0;
24
25 if (!::GetExitCodeProcess(handle, &tmp_exit_code)) {
[email protected]ad8cfa92014-05-21 20:06:2326 DPLOG(FATAL) << "GetExitCodeProcess() failed";
Wez05c2c682017-08-17 16:20:1127
28 // This really is a random number. We haven't received any
29 // information about the exit code, presumably because this
30 // process doesn't have permission to get the exit code, or
31 // because of some other cause for GetExitCodeProcess to fail
32 // (MSDN docs don't give the possible failure error codes for
33 // this function, so it could be anything). But we don't want
34 // to leave exit_code uninitialized, since that could cause
35 // random interpretations of the exit code. So we assume it
36 // terminated "normally" in this case.
Bruce Dawsonec0158512017-11-16 09:10:4037 *exit_code = win::kNormalTerminationExitCode;
Wez05c2c682017-08-17 16:20:1138
[email protected]307af212013-07-10 18:36:0939 // Assume the child has exited normally if we can't get the exit
40 // code.
41 return TERMINATION_STATUS_NORMAL_TERMINATION;
42 }
43 if (tmp_exit_code == STILL_ACTIVE) {
44 DWORD wait_result = WaitForSingleObject(handle, 0);
45 if (wait_result == WAIT_TIMEOUT) {
Peter Kasting4d3664b2022-06-16 19:27:5446 *exit_code = static_cast<int>(wait_result);
[email protected]307af212013-07-10 18:36:0947 return TERMINATION_STATUS_STILL_RUNNING;
48 }
49
50 if (wait_result == WAIT_FAILED) {
[email protected]ad8cfa92014-05-21 20:06:2351 DPLOG(ERROR) << "WaitForSingleObject() failed";
[email protected]307af212013-07-10 18:36:0952 } else {
53 DCHECK_EQ(WAIT_OBJECT_0, wait_result);
54
55 // Strange, the process used 0x103 (STILL_ACTIVE) as exit code.
56 NOTREACHED();
57 }
58
59 return TERMINATION_STATUS_ABNORMAL_TERMINATION;
60 }
61
Peter Kasting4d3664b2022-06-16 19:27:5462 *exit_code = static_cast<int>(tmp_exit_code);
[email protected]307af212013-07-10 18:36:0963
Will Harris07925d12019-10-31 03:03:0564 // clang-format off
[email protected]307af212013-07-10 18:36:0965 switch (tmp_exit_code) {
Bruce Dawsonec0158512017-11-16 09:10:4066 case win::kNormalTerminationExitCode:
[email protected]307af212013-07-10 18:36:0967 return TERMINATION_STATUS_NORMAL_TERMINATION;
Bruce Dawsonec0158512017-11-16 09:10:4068 case win::kDebuggerInactiveExitCode: // STATUS_DEBUGGER_INACTIVE.
69 case win::kKeyboardInterruptExitCode: // Control-C/end session.
70 case win::kDebuggerTerminatedExitCode: // Debugger terminated process.
71 case win::kProcessKilledExitCode: // Task manager kill.
[email protected]307af212013-07-10 18:36:0972 return TERMINATION_STATUS_PROCESS_WAS_KILLED;
Bruce Dawsonec0158512017-11-16 09:10:4073 case win::kSandboxFatalMemoryExceeded: // Terminated process due to
74 // exceeding the sandbox job
75 // object memory limits.
76 case win::kOomExceptionCode: // Ran out of memory.
wfhfa40c2722016-07-26 01:12:2877 return TERMINATION_STATUS_OOM;
Will Harris07925d12019-10-31 03:03:0578 // This exit code means the process failed an OS integrity check.
79 // This is tested in ProcessMitigationsTest.* in sandbox.
80 case win::kStatusInvalidImageHashExitCode:
81 return TERMINATION_STATUS_INTEGRITY_FAILURE;
[email protected]307af212013-07-10 18:36:0982 default:
83 // All other exit codes indicate crashes.
84 return TERMINATION_STATUS_PROCESS_CRASHED;
85 }
Will Harris07925d12019-10-31 03:03:0586 // clang-format on
[email protected]307af212013-07-10 18:36:0987}
88
[email protected]307af212013-07-10 18:36:0989bool WaitForProcessesToExit(const FilePath::StringType& executable_name,
rvargas2f70a152015-02-24 00:28:1190 TimeDelta wait,
[email protected]307af212013-07-10 18:36:0991 const ProcessFilter* filter) {
[email protected]307af212013-07-10 18:36:0992 bool result = true;
93 DWORD start_time = GetTickCount();
94
95 NamedProcessIterator iter(executable_name, filter);
[email protected]ed8e57da2014-07-03 07:03:3996 for (const ProcessEntry* entry = iter.NextProcessEntry(); entry;
97 entry = iter.NextProcessEntry()) {
avibeced7c2015-12-24 06:47:5998 DWORD remaining_wait = static_cast<DWORD>(
99 std::max(static_cast<int64_t>(0),
100 wait.InMilliseconds() - (GetTickCount() - start_time)));
brucedawsond3509432015-09-18 18:28:13101 HANDLE process = OpenProcess(SYNCHRONIZE,
102 FALSE,
103 entry->th32ProcessID);
104 DWORD wait_result = WaitForSingleObject(process, remaining_wait);
105 CloseHandle(process);
[email protected]ed8e57da2014-07-03 07:03:39106 result &= (wait_result == WAIT_OBJECT_0);
[email protected]307af212013-07-10 18:36:09107 }
108
109 return result;
110}
111
[email protected]307af212013-07-10 18:36:09112bool CleanupProcesses(const FilePath::StringType& executable_name,
rvargas2f70a152015-02-24 00:28:11113 TimeDelta wait,
[email protected]307af212013-07-10 18:36:09114 int exit_code,
115 const ProcessFilter* filter) {
[email protected]ed8e57da2014-07-03 07:03:39116 if (WaitForProcessesToExit(executable_name, wait, filter))
117 return true;
118 KillProcesses(executable_name, exit_code, filter);
119 return false;
[email protected]307af212013-07-10 18:36:09120}
121
[email protected]307af212013-07-10 18:36:09122} // namespace base