1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This file contains routines to kill processes and get the exit code and 6 // termination status. 7 8 #ifndef BASE_PROCESS_KILL_H_ 9 #define BASE_PROCESS_KILL_H_ 10 11 #include "base/files/file_path.h" 12 #include "base/process/process.h" 13 #include "base/process/process_handle.h" 14 #include "base/time/time.h" 15 #include "build/build_config.h" 16 17 namespace base { 18 19 class ProcessFilter; 20 21 #if defined(OS_WIN) 22 namespace win { 23 24 // See definition in sandbox/win/src/sandbox_types.h 25 const DWORD kSandboxFatalMemoryExceeded = 7012; 26 27 // Exit codes with special meanings on Windows. 28 const DWORD kNormalTerminationExitCode = 0; 29 const DWORD kDebuggerInactiveExitCode = 0xC0000354; 30 const DWORD kKeyboardInterruptExitCode = 0xC000013A; 31 const DWORD kDebuggerTerminatedExitCode = 0x40010004; 32 33 // This exit code is used by the Windows task manager when it kills a 34 // process. It's value is obviously not that unique, and it's 35 // surprising to me that the task manager uses this value, but it 36 // seems to be common practice on Windows to test for it as an 37 // indication that the task manager has killed something if the 38 // process goes away. 39 const DWORD kProcessKilledExitCode = 1; 40 41 } // namespace win 42 43 #endif // OS_WIN 44 45 // Return status values from GetTerminationStatus. Don't use these as 46 // exit code arguments to KillProcess*(), use platform/application 47 // specific values instead. 48 enum TerminationStatus { 49 TERMINATION_STATUS_NORMAL_TERMINATION, // zero exit status 50 TERMINATION_STATUS_ABNORMAL_TERMINATION, // non-zero exit status 51 TERMINATION_STATUS_PROCESS_WAS_KILLED, // e.g. SIGKILL or task manager kill 52 TERMINATION_STATUS_PROCESS_CRASHED, // e.g. Segmentation fault 53 TERMINATION_STATUS_STILL_RUNNING, // child hasn't exited yet 54 #if defined(OS_CHROMEOS) 55 // Used for the case when oom-killer kills a process on ChromeOS. 56 TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM, 57 #endif 58 #if defined(OS_ANDROID) 59 // On Android processes are spawned from the system Zygote and we do not get 60 // the termination status. We can't know if the termination was a crash or an 61 // oom kill for sure, but we can use status of the strong process bindings as 62 // a hint. 63 TERMINATION_STATUS_OOM_PROTECTED, // child was protected from oom kill 64 #endif 65 TERMINATION_STATUS_LAUNCH_FAILED, // child process never launched 66 TERMINATION_STATUS_OOM, // Process died due to oom 67 TERMINATION_STATUS_MAX_ENUM 68 }; 69 70 // Attempts to kill all the processes on the current machine that were launched 71 // from the given executable name, ending them with the given exit code. If 72 // filter is non-null, then only processes selected by the filter are killed. 73 // Returns true if all processes were able to be killed off, false if at least 74 // one couldn't be killed. 75 BASE_EXPORT bool KillProcesses(const FilePath::StringType& executable_name, 76 int exit_code, 77 const ProcessFilter* filter); 78 79 #if defined(OS_POSIX) 80 // Attempts to kill the process group identified by |process_group_id|. Returns 81 // true on success. 82 BASE_EXPORT bool KillProcessGroup(ProcessHandle process_group_id); 83 #endif // defined(OS_POSIX) 84 85 // Get the termination status of the process by interpreting the 86 // circumstances of the child process' death. |exit_code| is set to 87 // the status returned by waitpid() on POSIX, and from GetExitCodeProcess() on 88 // Windows, and may not be null. Note that on Linux, this function 89 // will only return a useful result the first time it is called after 90 // the child exits (because it will reap the child and the information 91 // will no longer be available). 92 BASE_EXPORT TerminationStatus GetTerminationStatus(ProcessHandle handle, 93 int* exit_code); 94 95 #if defined(OS_POSIX) 96 // Send a kill signal to the process and then wait for the process to exit 97 // and get the termination status. 98 // 99 // This is used in situations where it is believed that the process is dead 100 // or dying (because communication with the child process has been cut). 101 // In order to avoid erroneously returning that the process is still running 102 // because the kernel is still cleaning it up, this will wait for the process 103 // to terminate. In order to avoid the risk of hanging while waiting for the 104 // process to terminate, send a SIGKILL to the process before waiting for the 105 // termination status. 106 // 107 // Note that it is not an option to call WaitForExitCode and then 108 // GetTerminationStatus as the child will be reaped when WaitForExitCode 109 // returns, and this information will be lost. 110 // 111 BASE_EXPORT TerminationStatus GetKnownDeadTerminationStatus( 112 ProcessHandle handle, int* exit_code); 113 114 #if defined(OS_LINUX) 115 // Spawns a thread to wait asynchronously for the child |process| to exit 116 // and then reaps it. 117 BASE_EXPORT void EnsureProcessGetsReaped(Process process); 118 #endif // defined(OS_LINUX) 119 #endif // defined(OS_POSIX) 120 121 // Registers |process| to be asynchronously monitored for termination, forcibly 122 // terminated if necessary, and reaped on exit. The caller should have signalled 123 // |process| to exit before calling this API. The API will allow a couple of 124 // seconds grace period before forcibly terminating |process|. 125 // TODO(https://crbug.com/806451): The Mac implementation currently blocks the 126 // calling thread for up to two seconds. 127 BASE_EXPORT void EnsureProcessTerminated(Process process); 128 129 // These are only sparingly used, and not needed on Fuchsia. They could be 130 // implemented if necessary. 131 #if !defined(OS_FUCHSIA) 132 // Wait for all the processes based on the named executable to exit. If filter 133 // is non-null, then only processes selected by the filter are waited on. 134 // Returns after all processes have exited or wait_milliseconds have expired. 135 // Returns true if all the processes exited, false otherwise. 136 BASE_EXPORT bool WaitForProcessesToExit( 137 const FilePath::StringType& executable_name, 138 base::TimeDelta wait, 139 const ProcessFilter* filter); 140 141 // Waits a certain amount of time (can be 0) for all the processes with a given 142 // executable name to exit, then kills off any of them that are still around. 143 // If filter is non-null, then only processes selected by the filter are waited 144 // on. Killed processes are ended with the given exit code. Returns false if 145 // any processes needed to be killed, true if they all exited cleanly within 146 // the wait_milliseconds delay. 147 BASE_EXPORT bool CleanupProcesses(const FilePath::StringType& executable_name, 148 base::TimeDelta wait, 149 int exit_code, 150 const ProcessFilter* filter); 151 #endif // !defined(OS_FUCHSIA) 152 153 } // namespace base 154 155 #endif // BASE_PROCESS_KILL_H_ 156