blob: 9b91c216373bf993c5d39a33a04773927592f560 [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// 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
David Sanders6e709942022-04-05 06:49:2611#include "base/base_export.h"
[email protected]307af212013-07-10 18:36:0912#include "base/files/file_path.h"
rvargas61812772014-12-05 03:14:5413#include "base/process/process.h"
[email protected]dd4b51262013-07-25 21:38:2314#include "base/process/process_handle.h"
[email protected]307af212013-07-10 18:36:0915#include "base/time/time.h"
avibeced7c2015-12-24 06:47:5916#include "build/build_config.h"
[email protected]307af212013-07-10 18:36:0917
18namespace base {
19
20class ProcessFilter;
21
Xiaohan Wang37e81612022-01-15 18:27:0022#if BUILDFLAG(IS_WIN)
wfh48c487e62016-07-27 22:48:4723namespace win {
24
25// See definition in sandbox/win/src/sandbox_types.h
26const DWORD kSandboxFatalMemoryExceeded = 7012;
27
Bruce Dawsonec0158512017-11-16 09:10:4028// Exit codes with special meanings on Windows.
29const DWORD kNormalTerminationExitCode = 0;
30const DWORD kDebuggerInactiveExitCode = 0xC0000354;
31const DWORD kKeyboardInterruptExitCode = 0xC000013A;
32const DWORD kDebuggerTerminatedExitCode = 0x40010004;
Will Harris07925d12019-10-31 03:03:0533const DWORD kStatusInvalidImageHashExitCode = 0xC0000428;
Bruce Dawsonec0158512017-11-16 09:10:4034
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.
41const DWORD kProcessKilledExitCode = 1;
42
wfh48c487e62016-07-27 22:48:4743} // namespace win
44
Xiaohan Wang37e81612022-01-15 18:27:0045#endif // BUILDFLAG(IS_WIN)
wfh48c487e62016-07-27 22:48:4746
François Doray8cadc162023-12-06 11:18:1447// 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.
Andrew Williams92dcbea2024-04-26 14:23:3353// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
54// GENERATED_JAVA_PREFIX_TO_STRIP: TERMINATION_STATUS_
S. Ganesh4e21a58a2025-04-15 17:13:3455enum TerminationStatus : int {
François Doray8cadc162023-12-06 11:18:1456 // 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,
Xiaohan Wang37e81612022-01-15 18:27:0066#if BUILDFLAG(IS_CHROMEOS)
François Doray8cadc162023-12-06 11:18:1467 // OOM-killer killed the process on ChromeOS.
68 TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM = 5,
oshima620225722015-06-04 19:45:2769#endif
Xiaohan Wang37e81612022-01-15 18:27:0070#if BUILDFLAG(IS_ANDROID)
[email protected]6bf2f782013-11-08 15:52:5371 // On Android processes are spawned from the system Zygote and we do not get
François Doray8cadc162023-12-06 11:18:1472 // the termination status. We can't know if the termination was a crash or an
[email protected]6bf2f782013-11-08 15:52:5373 // oom kill for sure, but we can use status of the strong process bindings as
74 // a hint.
François Doray8cadc162023-12-06 11:18:1475 TERMINATION_STATUS_OOM_PROTECTED = 6,
[email protected]6bf2f782013-11-08 15:52:5376#endif
François Doray8cadc162023-12-06 11:18:1477 // Child process never launched.
78 TERMINATION_STATUS_LAUNCH_FAILED = 7,
79 // Out of memory.
80 TERMINATION_STATUS_OOM = 8,
Xiaohan Wang37e81612022-01-15 18:27:0081#if BUILDFLAG(IS_WIN)
Will Harris07925d12019-10-31 03:03:0582 // On Windows, the OS terminated process due to code integrity failure.
François Doray8cadc162023-12-06 11:18:1483 TERMINATION_STATUS_INTEGRITY_FAILURE = 9,
Will Harris07925d12019-10-31 03:03:0584#endif
François Doray8cadc162023-12-06 11:18:1485 TERMINATION_STATUS_MAX_ENUM = 10,
[email protected]307af212013-07-10 18:36:0986};
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.
93BASE_EXPORT bool KillProcesses(const FilePath::StringType& executable_name,
94 int exit_code,
95 const ProcessFilter* filter);
96
[email protected]307af212013-07-10 18:36:0997// Get the termination status of the process by interpreting the
98// circumstances of the child process' death. |exit_code| is set to
Wez05c2c682017-08-17 16:20:1199// the status returned by waitpid() on POSIX, and from GetExitCodeProcess() on
100// Windows, and may not be null. Note that on Linux, this function
[email protected]307af212013-07-10 18:36:09101// 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).
104BASE_EXPORT TerminationStatus GetTerminationStatus(ProcessHandle handle,
105 int* exit_code);
106
Xiaohan Wang37e81612022-01-15 18:27:00107#if BUILDFLAG(IS_POSIX)
[email protected]0dac68b42013-09-17 03:50:22108// 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//
Peter Kasting134ef9af2024-12-28 02:30:09123BASE_EXPORT TerminationStatus
124GetKnownDeadTerminationStatus(ProcessHandle handle, int* exit_code);
Wezc18a57c2018-04-02 20:20:14125
Xiaohan Wang37e81612022-01-15 18:27:00126#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
Wezc18a57c2018-04-02 20:20:14127// Spawns a thread to wait asynchronously for the child |process| to exit
128// and then reaps it.
129BASE_EXPORT void EnsureProcessGetsReaped(Process process);
Xiaohan Wang37e81612022-01-15 18:27:00130#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
131#endif // BUILDFLAG(IS_POSIX)
[email protected]307af212013-07-10 18:36:09132
Wezc18a57c2018-04-02 20:20:14133// 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|.
Alison Gale923a33e2024-04-22 23:34:28137// TODO(crbug.com/41367359): The Mac implementation currently blocks the
Wezc18a57c2018-04-02 20:20:14138// calling thread for up to two seconds.
139BASE_EXPORT void EnsureProcessTerminated(Process process);
140
Dave Tapuska31c385c2024-04-12 18:43:11141// 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)
[email protected]307af212013-07-10 18:36:09144// 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.
148BASE_EXPORT bool WaitForProcessesToExit(
149 const FilePath::StringType& executable_name,
150 base::TimeDelta wait,
151 const ProcessFilter* filter);
152
[email protected]307af212013-07-10 18:36:09153// 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.
159BASE_EXPORT bool CleanupProcesses(const FilePath::StringType& executable_name,
160 base::TimeDelta wait,
161 int exit_code,
162 const ProcessFilter* filter);
Dave Tapuska31c385c2024-04-12 18:43:11163#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.
168void WaitForChildToDie(pid_t child, int timeout_seconds);
169#endif // BUILDFLAG(IS_MAC) || (BUILDFLAG(IS_IOS) && TARGET_OS_SIMULATOR)
[email protected]307af212013-07-10 18:36:09170
[email protected]307af212013-07-10 18:36:09171} // namespace base
172
173#endif // BASE_PROCESS_KILL_H_