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