I ran into this issue at work in a test runner we have that is written in Go and runs a test suite which is a node module, which itself spawns several subprocesses. The issue was that one of the subprocesses inherited its parents' stdout file descriptor, but would outlive the parent process being killed. If you use Go's exec.Cmd
to run a process and set its Stdout
or Stderr
to something that is not a File
, a goroutine will be spawned to drive that I/O when calling Cmd.Start
, and all such goroutines will be run to completion as part of Cmd.Wait
. In this situation, because the grandchild process stays alive, it keeps the stdout pipe open, thus Cmd.Wait
blocks until it exits.
subprocess.go
is a minimal testcase to display the issue. It spawns itself as a child process with piped stdout, then waits one second before killing the subprocess and waiting on it. The child process spawns itself as a grandchild with inherited stdout and sleeps for 5 seconds before exiting. The grandchild process simply