[flang-commits] [flang] 5a7f9a5 - [flang] use setsid to assign the child to prevent zombie as it will be clean up by init process (#77944)

via flang-commits flang-commits at lists.llvm.org
Fri Jan 19 06:19:01 PST 2024


Author: Yi Wu
Date: 2024-01-19T14:18:57Z
New Revision: 5a7f9a5a9c85c9b7851bbf267f5a12b9211f810e

URL: https://github.com/llvm/llvm-project/commit/5a7f9a5a9c85c9b7851bbf267f5a12b9211f810e
DIFF: https://github.com/llvm/llvm-project/commit/5a7f9a5a9c85c9b7851bbf267f5a12b9211f810e.diff

LOG: [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

Added: 
    

Modified: 
    flang/runtime/execute.cpp
    flang/unittests/Runtime/CommandTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/execute.cpp b/flang/runtime/execute.cpp
index d38cb8384bc8640..c84930c5c3287c0 100644
--- a/flang/runtime/execute.cpp
+++ b/flang/runtime/execute.cpp
@@ -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);

diff  --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 4c3618d0e3d903b..b2f6fe6177ed57e 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -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:


        


More information about the flang-commits mailing list