mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 05:40:09 +00:00
[flang] use setsid to assign the child to prevent zombie as it will be clean up by init process (#77944)
When using `setsid()` in a child process created by `fork()`, a new session is created, and the child becomes a session leader. If the parent process terminates before the child, the child becomes an orphan and is adopted by the `init` process. The `init` process will eventually clean up the child process once it exits. However, killing the parent does not automatically kill the child; the child will continue running until it exits. Proper cleanup involves waiting for the child process to exit using `wait()` or `waitpid()` in the parent process to avoid zombie processes, but this approach is not valid for `EXECUTE_COMMAND_LINE` with async mode. Fix: https://github.com/llvm/llvm-project/issues/77803
This commit is contained in:
parent
eaa8def929
commit
5a7f9a5a9c
@ -181,8 +181,6 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
|
||||
}
|
||||
FreeMemory(wcmd);
|
||||
#else
|
||||
// terminated children do not become zombies
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
pid_t pid{fork()};
|
||||
if (pid < 0) {
|
||||
if (!cmdstat) {
|
||||
@ -192,6 +190,19 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait,
|
||||
CheckAndCopyCharsToDescriptor(cmdmsg, "Fork failed");
|
||||
}
|
||||
} else if (pid == 0) {
|
||||
// Create a new session, let init process take care of zombie child
|
||||
if (setsid() == -1) {
|
||||
if (!cmdstat) {
|
||||
terminator.Crash("setsid() failed with errno: %d, asynchronous "
|
||||
"process initiation failed.",
|
||||
errno);
|
||||
} else {
|
||||
StoreIntToDescriptor(cmdstat, ASYNC_NO_SUPPORT_ERR, terminator);
|
||||
CheckAndCopyCharsToDescriptor(cmdmsg,
|
||||
"setsid() failed, asynchronous process initiation failed.");
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int status{std::system(newCmd)};
|
||||
TerminationCheck(status, cmdstat, cmdmsg, terminator);
|
||||
exit(status);
|
||||
|
@ -404,6 +404,24 @@ TEST_F(ZeroArguments, ECLInvalidCommandParentNotTerminatedAsync) {
|
||||
CheckDescriptorEqStr(cmdMsg.get(), "No change");
|
||||
}
|
||||
|
||||
TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectSync) {
|
||||
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
|
||||
|
||||
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
|
||||
*command.get(), false, nullptr, nullptr, nullptr));
|
||||
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
|
||||
*command.get(), true, nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectAsync) {
|
||||
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
|
||||
|
||||
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
|
||||
*command.get(), false, nullptr, nullptr, nullptr));
|
||||
EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
|
||||
*command.get(), false, nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};
|
||||
class OneArgument : public CommandFixture {
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user