• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
54 // GENERATED_JAVA_PREFIX_TO_STRIP: TERMINATION_STATUS_
55 enum TerminationStatus {
56   // Zero exit status.
57   TERMINATION_STATUS_NORMAL_TERMINATION = 0,
58   // Other abnormal termination reason.
59   TERMINATION_STATUS_ABNORMAL_TERMINATION = 1,
60   // E.g. SIGKILL or task manager kill.
61   TERMINATION_STATUS_PROCESS_WAS_KILLED = 2,
62   // E.g. Segmentation fault.
63   TERMINATION_STATUS_PROCESS_CRASHED = 3,
64   // Child hasn't exited yet.
65   TERMINATION_STATUS_STILL_RUNNING = 4,
66 #if BUILDFLAG(IS_CHROMEOS)
67   // OOM-killer killed the process on ChromeOS.
68   TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM = 5,
69 #endif
70 #if BUILDFLAG(IS_ANDROID)
71   // On Android processes are spawned from the system Zygote and we do not get
72   // the termination status. We can't know if the termination was a crash or an
73   // oom kill for sure, but we can use status of the strong process bindings as
74   // a hint.
75   TERMINATION_STATUS_OOM_PROTECTED = 6,
76 #endif
77   // Child process never launched.
78   TERMINATION_STATUS_LAUNCH_FAILED = 7,
79   // Out of memory.
80   TERMINATION_STATUS_OOM = 8,
81 #if BUILDFLAG(IS_WIN)
82   // On Windows, the OS terminated process due to code integrity failure.
83   TERMINATION_STATUS_INTEGRITY_FAILURE = 9,
84 #endif
85   TERMINATION_STATUS_MAX_ENUM = 10,
86 };
87 
88 // Attempts to kill all the processes on the current machine that were launched
89 // from the given executable name, ending them with the given exit code.  If
90 // filter is non-null, then only processes selected by the filter are killed.
91 // Returns true if all processes were able to be killed off, false if at least
92 // one couldn't be killed.
93 BASE_EXPORT bool KillProcesses(const FilePath::StringType& executable_name,
94                                int exit_code,
95                                const ProcessFilter* filter);
96 
97 // Get the termination status of the process by interpreting the
98 // circumstances of the child process' death. |exit_code| is set to
99 // the status returned by waitpid() on POSIX, and from GetExitCodeProcess() on
100 // Windows, and may not be null.  Note that on Linux, this function
101 // will only return a useful result the first time it is called after
102 // the child exits (because it will reap the child and the information
103 // will no longer be available).
104 BASE_EXPORT TerminationStatus GetTerminationStatus(ProcessHandle handle,
105                                                    int* exit_code);
106 
107 #if BUILDFLAG(IS_POSIX)
108 // Send a kill signal to the process and then wait for the process to exit
109 // and get the termination status.
110 //
111 // This is used in situations where it is believed that the process is dead
112 // or dying (because communication with the child process has been cut).
113 // In order to avoid erroneously returning that the process is still running
114 // because the kernel is still cleaning it up, this will wait for the process
115 // to terminate. In order to avoid the risk of hanging while waiting for the
116 // process to terminate, send a SIGKILL to the process before waiting for the
117 // termination status.
118 //
119 // Note that it is not an option to call WaitForExitCode and then
120 // GetTerminationStatus as the child will be reaped when WaitForExitCode
121 // returns, and this information will be lost.
122 //
123 BASE_EXPORT TerminationStatus GetKnownDeadTerminationStatus(
124     ProcessHandle handle, int* exit_code);
125 
126 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
127 // Spawns a thread to wait asynchronously for the child |process| to exit
128 // and then reaps it.
129 BASE_EXPORT void EnsureProcessGetsReaped(Process process);
130 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
131 #endif  // BUILDFLAG(IS_POSIX)
132 
133 // Registers |process| to be asynchronously monitored for termination, forcibly
134 // terminated if necessary, and reaped on exit. The caller should have signalled
135 // |process| to exit before calling this API. The API will allow a couple of
136 // seconds grace period before forcibly terminating |process|.
137 // TODO(crbug.com/41367359): The Mac implementation currently blocks the
138 // calling thread for up to two seconds.
139 BASE_EXPORT void EnsureProcessTerminated(Process process);
140 
141 // These are only sparingly used, and not needed on Fuchsia or iOS. They could
142 // be implemented if necessary.
143 #if !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)
144 // Wait for all the processes based on the named executable to exit.  If filter
145 // is non-null, then only processes selected by the filter are waited on.
146 // Returns after all processes have exited or wait_milliseconds have expired.
147 // Returns true if all the processes exited, false otherwise.
148 BASE_EXPORT bool WaitForProcessesToExit(
149     const FilePath::StringType& executable_name,
150     base::TimeDelta wait,
151     const ProcessFilter* filter);
152 
153 // Waits a certain amount of time (can be 0) for all the processes with a given
154 // executable name to exit, then kills off any of them that are still around.
155 // If filter is non-null, then only processes selected by the filter are waited
156 // on.  Killed processes are ended with the given exit code.  Returns false if
157 // any processes needed to be killed, true if they all exited cleanly within
158 // the wait_milliseconds delay.
159 BASE_EXPORT bool CleanupProcesses(const FilePath::StringType& executable_name,
160                                   base::TimeDelta wait,
161                                   int exit_code,
162                                   const ProcessFilter* filter);
163 #endif  // !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)
164 
165 #if BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && TARGET_OS_SIMULATOR)
166 // This is common code used by kill_ios.cc when building with iOS simulator it
167 // does not need to be exported.
168 void WaitForChildToDie(pid_t child, int timeout_seconds);
169 #endif  // BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && TARGET_OS_SIMULATOR)
170 
171 }  // namespace base
172 
173 #endif  // BASE_PROCESS_KILL_H_
174