Description
On POSIX platforms, a C program that uses fork
to spawn a child process must subsequently call wait
or similar to reap any resulting zombies. However, the call to wait
is not needed if the process explicitly sets the handler for SIGCHLD
to SIG_IGN
or sets the SA_NOCLDWAIT
flag on that handler.
On those same platforms, Go's os/exec
package uses fork
under the hood (via os.StartProcess
, syscall.StartProcess
, and ultimately syscall.forkExec
). However, (*exec.Cmd).Start
doesn't document whether Wait
must actually be called. The documentation today says:
The
Wait
method will return the exit code and release associated resources once the command exits.
That seems to imply that Wait
must be called in order to release those resources, but that isn't entirely obvious to me — given the finalizers that the standard library already uses for os.File
, one might assume that the child process does not need to be explicitly reaped if the caller doesn't care about the exit code and hasn't allocated explicit resources that would need to be released (for example, because they set Stdin
, Stdout
, and/or Stderr
to either nil
or instances of *os.File
).
I think that (*exec.Cmd).Start
should either clearly state that Wait
must always be called (and perhaps diagnose violations with a finalizer), or avoid unbounded resource leaks if Wait
is not called.
I think the latter is fairly easy to implement at the cost of one extra goroutine per Cmd
(by moving the Wait
call into an eager goroutine), and that would also enable a clean fix for #28461 (#15103 notwithstanding).
@ianlancetaylor, @bradfitz: does that seem like a reasonable resolution?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status