-
Notifications
You must be signed in to change notification settings - Fork 18k
os/exec: example test using Command.Stdout causes data race #17769
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'll give it a shot if this issue is not already taken. |
The Run call is racing with the shutdown of the test. I'm not sure how much we actually care about this data race - in practice you are not going to have your program exit as you're in the midst of attempting to start a child process. @Dhananjay92 You're welcome to investigate trying to fix this. |
I don't see any locking/synchronization in |
FWIW, the same race detector report is printed when a package example_test
import (
"fmt"
"os"
"os/exec"
"time"
)
func ExampleFoo() {
fmt.Println("foo")
cmd := exec.Command("/bin/sh", "-c", "sleep 999d")
cmd.Stdout = os.Stdout
go cmd.Run()
time.Sleep(1 * time.Second)
// OUTPUT:
// foo
} I don’t 100% understand why the race detector is flagging this, but in the real-life situtation in which I encountered this issue, I don’t think a child process was being started while the test was exiting. Rather, that child process was already running. |
The race detector doesn't care about sleeps. It cares about reads and writes of the same memory location with no happens-before relationship (see https://golang.org/ref/mem). This is a race between the close of As far as I can tell this is a real race. The code in package example is going to close stdout. At the same time, the goroutine is getting stdout's file descriptor to pass it to the child process. There is no synchronization between those two steps, and even if something were added it would still be a race whether the child process got an open file descriptor or not. So, closing. |
Thanks for looking into this. I don’t entirely understand what closing this issue implies. Are you saying that one must not use os.Stdout in example code? |
It's fine to use Basically, don't write
in an example with a |
Thanks for clarifying. In the scenario where this issue was filed from, a library external to my code was creating a subprocess with IIUC, the data race happens if and only if processes are not terminated correctly. I’ll take this up with the authors of said library, possibly there’s a bug related to context cancellation here. |
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?What did you do?
The following example test triggers a data race:
In case it matters, I’m running
go test -race -v examplerace/...
, the above example is stored ingocode/src/examplerace/example_test.go
What did you expect to see?
I expected the test to pass.
What did you see instead?
The test triggers a data race:
The text was updated successfully, but these errors were encountered: