-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
doc: document that unsynchronized (channel send + channel close) is a data race #27769
Comments
It's reported as a data race, but in reality it's a "your send and close are unordered" error. What it means is that although in this execution the send came before the close, there's no observable ordering enforcing that - the next time you run, it only takes different choices by the scheduler to make the send come after the close and cause a panic. |
@randall77 - thanks for the explanation. I think that is an understandable reasoning on why the race detector trips. I'm just questioning if this behavior should be documented...if so where would such docs belong? |
@deckarep: I don't really know where such documentation should live. We have docs about how to use the race detector, but I don't see any place to describe the kind of races it finds. |
What @randall77 said. Re documenting, I don't think there is a single doc that all users of race detector has read before using it. Thus I don't think this can be solved with documentation. But we could mention this in https://golang.org/doc/articles/race_detector.html#Typical_Data_Races |
I’m happy to take a crack and write something up to start off the docs. Then I can consult the Go team to help with wording and accuracy. |
I think https://golang.org/ref/mem under the Channel communication section might also be a good place to mention it since the send on the channel may happen before its closure. |
It would be nice if the documentation also mentioned that this race is a symptom of ineffective producer/consumer designation, not just ordering quirks in the program. |
@deckarep are you still interested in doing this? |
Hope it's okay to bring this up nearly a year after. I'm looking to contribute for the first time, and documentation seems a safe and easy place to start. The following code still produces a data race. func TestRace(t *testing.T) {
var c = make(chan byte, 20)
go func() {
defer func() {
if r := recover(); r == nil {
t.Error("expected panic error")
}
}()
for i := 0; i < 25; i++ {
c <- byte(0)
}
t.Error("expected a panic")
}()
close(c)
} I could draft a paragraph to document this on https://golang.org/doc/articles/race_detector.html#Typical_Data_Races and get some feedback. Does it sound okay to you? |
Change https://golang.org/cl/196681 mentions this issue: |
Change https://golang.org/cl/219637 mentions this issue: |
TBufferedServer.Close() may close the data channel before Serve detects it. Move chan close() to Serve to prevent a panic caused by sending on a closed channel. See also golang/go#27769 (comment) === RUN TestTBufferedServer_SendReceive ================== WARNING: DATA RACE Write at 0x00c000074850 by goroutine 9: runtime.closechan() /home/travis/.gimme/versions/go1.15.2.linux.amd64/src/runtime/chan.go:352 +0x0 github.com/jaegertracing/jaeger/cmd/agent/app/servers.(*TBufferedServer).Stop() ... Previous read at 0x00c000074850 by goroutine 10: runtime.chansend() /home/travis/.gimme/versions/go1.15.2.linux.amd64/src/runtime/chan.go:158 +0x0 github.com/jaegertracing/jaeger/cmd/agent/app/servers.(*TBufferedServer).Serve() /home/travis/gopath/src/github.com/jaegertracing/jaeger/cmd/agent/app/servers/tbuffered_server.go:97 +0x264 ... ================== testing.go:1042: race detected during execution of test --- FAIL: TestTBufferedServer_SendReceive (0.01s) Closes jaegertracing#2577 Signed-off-by: Carl Henrik Lunde <chlunde@ifi.uio.no>
TBufferedServer.Close() may close the data channel before Serve detects it. Move chan close() to Serve to prevent a panic caused by sending on a closed channel. See also golang/go#27769 (comment) === RUN TestTBufferedServer_SendReceive ================== WARNING: DATA RACE Write at 0x00c000074850 by goroutine 9: runtime.closechan() /home/travis/.gimme/versions/go1.15.2.linux.amd64/src/runtime/chan.go:352 +0x0 github.com/jaegertracing/jaeger/cmd/agent/app/servers.(*TBufferedServer).Stop() ... Previous read at 0x00c000074850 by goroutine 10: runtime.chansend() /home/travis/.gimme/versions/go1.15.2.linux.amd64/src/runtime/chan.go:158 +0x0 github.com/jaegertracing/jaeger/cmd/agent/app/servers.(*TBufferedServer).Serve() /home/travis/gopath/src/github.com/jaegertracing/jaeger/cmd/agent/app/servers/tbuffered_server.go:97 +0x264 ... ================== testing.go:1042: race detected during execution of test --- FAIL: TestTBufferedServer_SendReceive (0.01s) Closes #2577 Signed-off-by: Carl Henrik Lunde <chlunde@ifi.uio.no>
Now that I'm aware of this behavior i'm only proposing that this be documented in Go's documentation. My rationale is that since channels are built to be threadsafe, I would have assumed all operations against them are threadsafe. ie, sending, receiving, closing.
What version of Go are you using (
go version
)? go version go1.11 darwin/amd64Does this issue reproduce with the latest release? Yes
What operating system and processor architecture are you using (
go env
)?What did you do?
First off, my code was flawed but it exposed a data-race that I thought would not be possible. My assumption was that all operations on channels are thread-safe by design..at the worst I would have expected the code to panic.
https://stackoverflow.com/questions/47714470/go-race-condition-when-closing-a-go-channel
What did you expect to see?
I expected a panic to occur but instead this data-race shows up.
What did you see instead?
The text was updated successfully, but these errors were encountered: