You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
getProcessExitCode/waitForProcess should throw ECHILD rather than return ExitSuccess for non-child process #359
ECHILD (for waitpid() or waitid()) The process specified by pid
(waitpid()) or idtype and id (waitid()) does not exist or
is not a child of the calling process. (This can happen
for one's own child if the action for SIGCHLD is set to
SIG_IGN. See also the Linux Notes section about threads.)
In https://github.com/well-typed/haskell-debugger, it took me a long while to uncover a bug that turned out to be caused by getProcessExitCode incorrectly returning Just ExitSuccess for a handle of a non-child process.
I'm "unsafely" (i.e with .Internals) constructing the handle from the PID of a process that was not spawned/is not a child of the process calling getProcessExitCode. It should throw something like ECHILD, following the manpage for wait.
I suspect waitForProcess should also fail with ECHILD here.
I've attached the AI generated counter example program I was using to observe the incorrect behavior outside of the much more complicated haskell-debugger
Hi @alt-romes, what do you mean it should "throw" ECHILD? Do you mean it should throw some sort of exception with the same meaning as the ECHILD error code? Do you have candidate for the type of this exception in mind, or would it have to be a new one?
Would it be possible to embed that code in a comment here (perhaps using the <details> and <summary> tags to collapse it)? It currently requires a download to view, which is inconvenient.
Digging into this more, it seems that the issue is that you created a ProcessHandle using internals in a way that violates the assumed invariant of that type (that it always refers to a child process), and you are saying that violation should be detected by getProcessExitCode (and other functions that take ProcessHandle as an argument) and it should throw an exception instead of returning the wrong result. Is that a correct interpretation?
Alternatively, does it make sense to say it is not an invariant of ProcessHandle that it refers to a child process, and nonetheless this condition should be detected by the various functions in the API here?
Regarding implementation, ECHILD is detected and we return 1 from the C getProcessExitCode:
I personally can' t see anything wrong with removing that special case for ECHILD. I believe this would give you the behaviour you want, @alt-romes. Does anyone else have any clearer idea (especially someone with more posix experience)?
Activity
tomjaguarpaw commentedon Apr 17, 2026
Hi @alt-romes, what do you mean it should "throw"
ECHILD? Do you mean it should throw some sort of exception with the same meaning as theECHILDerror code? Do you have candidate for the type of this exception in mind, or would it have to be a new one?Would it be possible to embed that code in a comment here (perhaps using the
<details>and<summary>tags to collapse it)? It currently requires a download to view, which is inconvenient.MangoIV commentedon Apr 22, 2026
The Code
alt-romes commentedon Apr 22, 2026
@tomjaguarpaw yes, some Haskell exception to mean the underling
ECHILDerror code. I don't know whether one already exists to represent it.tomjaguarpaw commentedon May 9, 2026
Digging into this more, it seems that the issue is that you created a
ProcessHandleusing internals in a way that violates the assumed invariant of that type (that it always refers to a child process), and you are saying that violation should be detected bygetProcessExitCode(and other functions that takeProcessHandleas an argument) and it should throw an exception instead of returning the wrong result. Is that a correct interpretation?Alternatively, does it make sense to say it is not an invariant of
ProcessHandlethat it refers to a child process, and nonetheless this condition should be detected by the various functions in the API here?Regarding implementation,
ECHILDis detected and we return1from the CgetProcessExitCode:process/cbits/posix/runProcess.c
Lines 237 to 241 in e27e2e2
1is treated as "it has exited":process/System/Process.hs
Lines 857 to 866 in e27e2e2
That certainly seems odd to me.
Related:
I personally can' t see anything wrong with removing that special case for
ECHILD. I believe this would give you the behaviour you want, @alt-romes. Does anyone else have any clearer idea (especially someone with more posix experience)?