From fd717778bcb4bc8e9aeb8d24ebda6b029921940e Mon Sep 17 00:00:00 2001 From: Aditya Mandaleeka Date: Fri, 6 Feb 2026 18:39:28 -0800 Subject: [PATCH] Handle ECHILD in ProcessWaitState.TryReapChild instead of FailFast. --- .../Diagnostics/ProcessWaitState.Unix.cs | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs index 042a95b1950c64..5254aae8907e90 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs @@ -581,9 +581,26 @@ private bool TryReapChild(bool configureConsole) } else { - // Unexpected. - int errorCode = Marshal.GetLastWin32Error(); - Environment.FailFast("Error while reaping child. errno = " + errorCode); + // waitpid returned -1 + Interop.Error error = Interop.Sys.GetLastError(); + if (error == Interop.Error.ECHILD) + { + // The child was already reaped by another waitpid call + // (e.g., by an original SIGCHLD handler invoked before + // the .NET handler, or by native code in the process). + // The exit code is unavailable since it was consumed by + // the other waiter; we leave _exitCode as null, similar + // to CheckForNonChildExit. + if (_usesTerminal) + { + Process.ConfigureTerminalForChildProcesses(-1, configureConsole); + } + + SetExited(); + return true; + } + + Environment.FailFast("Error while reaping child. errno = " + Marshal.GetLastWin32Error()); } return false; }