-
Notifications
You must be signed in to change notification settings - Fork 18k
os/exec: documentation unclear on whether (*Cmd).Wait
must be called
#52580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I will note that at the moment, (Compare https://go.dev/play/p/mNn6W6J9iDZ vs. https://go.dev/play/p/OQc3BPJfSBQ.) |
(This was noticed while prototyping an in-tree implementation of #50436.) |
The docs for the My main concern with a simple approach to automatically waiting is that it uses up more than a goroutine, it uses up a thread. I don't think we want to burn a thread per child process automatically and unnecessarily. We could in principle use a |
Just chiming into say that i had this exact question recently. More guidance from the docs would certainly be appreciated 😄 In my case, i was reading output from a command. When i was done with the portion i was interested in, i didn't care what happened to the process, just that it went away. Ended up deferring cmd := exec.Command("ndisasm", "...")
pipe, err := cmd.StdoutPipe()
if err != nil {
t.Fatal(err)
}
defer func() { cmd.Process.Kill(); cmd.Wait() }()
defer pipe.Close()
cmd.Start() |
Change https://go.dev/cl/414056 mentions this issue: |
Fixes golang#52580 Change-Id: Ib2dd8a793b9c6fcb083abb3f7c346f6279adefc9 Reviewed-on: https://go-review.googlesource.com/c/go/+/414056 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Alan Donovan <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
Change https://go.dev/cl/436655 mentions this issue: |
Change https://go.dev/cl/436656 mentions this issue: |
Updates #52580. For #50436. Change-Id: I0929055ffca1ca429f6ebec7d877f4268bd1fda2 Reviewed-on: https://go-review.googlesource.com/c/go/+/436656 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Auto-Submit: Bryan Mills <[email protected]> Reviewed-by: Benny Siegert <[email protected]>
Updates #52580. For #50436. Change-Id: I669f13863f1f85d576c3c94500b118e6989000eb Reviewed-on: https://go-review.googlesource.com/c/go/+/436655 Auto-Submit: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Run-TryBot: Bryan Mills <[email protected]>
Change https://go.dev/cl/460998 mentions this issue: |
In CL 436655 I added a GODEBUG setting to this test process to verify that Wait is eventually called for every exec.Cmd before it becomes unreachable. However, the cmdHang test helpers in TestWaitInterrupt/Exit-hang and TestWaitInterrupt/SIGKILL-hang intentially leak a subprocess in order to simulate a leaky third-party program, as Go users might encounter in practical use. To avoid tripping over the leak check, we call Wait on the leaked subprocess in a background goroutine. Since we expect the process running cmdHang to exit before its subprocess does, the call to Wait should have no effect beyond suppressing the leak check. Fixes #57596. Updates #52580. Updates #50436. Change-Id: Ia4b88ea47fc6b605c27ca6d9d7669c874867a900 Reviewed-on: https://go-review.googlesource.com/c/go/+/460998 Run-TryBot: Bryan Mills <[email protected]> Auto-Submit: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
On POSIX platforms, a C program that uses
fork
to spawn a child process must subsequently callwait
or similar to reap any resulting zombies. However, the call towait
is not needed if the process explicitly sets the handler forSIGCHLD
toSIG_IGN
or sets theSA_NOCLDWAIT
flag on that handler.On those same platforms, Go's
os/exec
package usesfork
under the hood (viaos.StartProcess
,syscall.StartProcess
, and ultimatelysyscall.forkExec
). However,(*exec.Cmd).Start
doesn't document whetherWait
must actually be called. The documentation today says: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 foros.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 setStdin
,Stdout
, and/orStderr
to eithernil
or instances of*os.File
).I think that
(*exec.Cmd).Start
should either clearly state thatWait
must always be called (and perhaps diagnose violations with a finalizer), or avoid unbounded resource leaks ifWait
is not called.I think the latter is fairly easy to implement at the cost of one extra goroutine per
Cmd
(by moving theWait
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?
The text was updated successfully, but these errors were encountered: