-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
os/exec: Inconsistent behaviour in exec.Cmd.Wait
#20730
Comments
I think this is another variant of #18874. I don't know how to fix that one, or this one either. There is no reason to set the |
@ianlancetaylor The problem, in my opinion, is that I expected |
Let's move discussion to #18874. Thanks. |
- Correctly detect when error channel is closed (potential fix for #134). Previously the logic was inverted for whether the channel was closed, so recovery was not initiated. Unit test TestOsqueryDies repros the suspected issue. - Allow logger to be set properly. - Add logging around recovery scenarios. - Check communication with both osquery and extension server in health check (previously only the extension server was checked). - Add healthcheck on interval that causes recovery on failure (Closes #141). - Do not set cmd output to ioutil.Discard. Causes a bug with cmd.Wait (see golang/go#20730)
- Correctly detect when error channel is closed (potential fix for #134). Previously the logic was inverted for whether the channel was closed, so recovery was not initiated. Unit test TestOsqueryDies repros the suspected issue. - Allow logger to be set properly. - Add logging around recovery scenarios. - Check communication with both osquery and extension server in health check (previously only the extension server was checked). - Add healthcheck on interval that causes recovery on failure (Closes #141). - Do not set cmd output to ioutil.Discard. Causes a bug with cmd.Wait (see golang/go#20730)
- Changes to public API to better reflect actual usage and ease implementation. - Use errgroup for coordination of process management/cleanup. This helps prevent leaking of goroutines (relative to existing implementation). - Fix bug in which osquery process was not restarted after failure. - Allow logger to be set properly. - Add logging around recovery scenarios. - Check communication with both osquery and extension server in health check (previously only the extension server was checked). - Add healthcheck on interval that initiates recovery on failure (Closes #141). - Do not set cmd output to ioutil.Discard. Causes a bug with cmd.Wait (see golang/go#20730).
What version of Go are you using (
go version
)?Note that I'm running Go using Docker for reproducibility (see below).
What operating system and processor architecture are you using (
go env
)?What did you do?
I created
main.go
, as follows:I ran it with the following Docker command:
I then uncommented the commented lines and ran the same command again.
What did you expect to see?
I expected the output of both invocations to match.
What did you see instead?
Running the program with output redirected to
ioutil.Discard
produced thefollowing output:
Running the program with output redirected to
io.Stdout
andio.Stderr
produced the following output:
The core issue in the above is that
cmd.Wait()
doesn't return when the commandexits in the case where
ioutil.Discard
is being used.Additional notes
I consider the second invocation to have the correct and expected output. This
opinion is backed up as it conforms with the operation of
os.Process
; a quicktest of this is to replace
cmd.Wait()
in the above code withcmd.Process.Wait()
in both invocations and see that the output matches that ofthe second invocation above.
The problem seems related to the child processes spawned by
git daemon
. Thiscan be further demonstrated by instead spawning
go run hello.go
with differentimplementations of
hello.go
, such as the following:main.go
runs without producing a timeout with this implementation ofhello.go
. Adding atime.Sleep(time.Second*5)
before thePrintln
in thisimplementation also causes no timeout. However, if the
Println
is instead putin an infinite
for
loop then a timeout occurs.It appears that
exec.Cmd.Wait
currently requires all processes in the processtree of the spawned process to exit before it can return. I suggest either
updating the behaviour to match that of
os.Process
, or else updating thedocumentation to reflect this behaviour.
The text was updated successfully, but these errors were encountered: