diff options
author | 2024-05-28 18:23:47 +0100 | |
---|---|---|
committer | 2024-05-30 17:20:17 +0000 | |
commit | 7afcee1180986d8b87773d173af7ecd63859ffe3 (patch) | |
tree | 19b1457fa895ee6354b55b13990cde9e7474e47e | |
parent | 6f208b3e645c82ce37eee7a8703adb9bb2109a71 (diff) |
Kill the child process when the parent process dies.
When we have a process hierarchy, such as artd->odrefresh->dex2oat, we
want to be able to kill a subtree. For example, if we kill odrefresh, we
want dex2oat to be killed as well; if we kill artd, we want both
odrefresh and dex2oat to be killed as well. This can be achieved by
PR_SET_PDEATHSIG.
Bug: 311377497
Test: Kill odrefresh and see dex2oat killed.
Change-Id: I28cc271f5c37b9ad50bee179eb9b211cb3545a2f
-rw-r--r-- | runtime/exec_utils.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/runtime/exec_utils.cc b/runtime/exec_utils.cc index 1266ed18f7..1914d506cd 100644 --- a/runtime/exec_utils.cc +++ b/runtime/exec_utils.cc @@ -17,6 +17,8 @@ #include "exec_utils.h" #include <poll.h> +#include <signal.h> +#include <sys/prctl.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> @@ -65,6 +67,10 @@ std::string ToCommandLine(const std::vector<std::string>& args) { // If there is a runtime (Runtime::Current != nullptr) then the subprocess is created with the // same environment that existed when the runtime was started. // Returns the process id of the child process on success, -1 otherwise. +// The child is killed as soon as the caller thread dies, the caller thread needs to stay around and +// wait for the child. Therefore, this function is most suitable to be used by +// `ExecAndReturnResult`, which does the wait. It's not suitable to be used for fire-and-forget +// exec's. pid_t ExecWithoutWait(const std::vector<std::string>& arg_vector, std::string* error_msg) { // Convert the args to char pointers. const char* program = arg_vector[0].c_str(); @@ -83,6 +89,12 @@ pid_t ExecWithoutWait(const std::vector<std::string>& arg_vector, std::string* e // change process groups, so we don't get reaped by ProcessManager setpgid(0, 0); + // Kill the child process when the parent process dies. + if (prctl(PR_SET_PDEATHSIG, SIGKILL) != 0) { + // This should never happen. + PLOG(FATAL) << "Failed to call prctl"; + } + // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc. // Use the snapshot of the environment from the time the runtime was created. char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot(); |