-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
net/http: data race in http/2 server #20704
Labels
FrozenDueToAge
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Comments
Simplified reproduction. Race is triggered on the first run for me. package main
import (
"crypto/tls"
"net/http"
"net/http/httptest"
"golang.org/x/net/http2"
)
const (
itemSize = 1 << 10
itemCount = 100
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for i := 0; i < itemCount; i++ {
_, err := w.Write(make([]byte, itemSize))
if err != nil {
return
}
}
})
srv := httptest.NewUnstartedServer(handler)
srv.TLS = &tls.Config{
NextProtos: []string{"h2"},
}
srv.StartTLS()
cl := &http.Client{
Transport: &http2.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
for i := 0; i < 10000; i++ {
resp, err := cl.Get(srv.URL)
if err != nil {
panic(err)
}
resp.Body.Close()
}
} |
bradfitz
added
the
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
label
Jun 17, 2017
/cc @tombergan |
CL https://golang.org/cl/46008 mentions this issue. |
gopherbot
pushed a commit
to golang/net
that referenced
this issue
Jun 19, 2017
With Tom Bergan. Updates golang/go#20704 Change-Id: Ib71202801f8c72af2f22865899c93df1f3753fdd Reviewed-on: https://go-review.googlesource.com/46008 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Tom Bergan <[email protected]>
CL https://golang.org/cl/46093 mentions this issue. |
c3mb0
pushed a commit
to c3mb0/net
that referenced
this issue
Apr 2, 2018
With Tom Bergan. Updates golang/go#20704 Change-Id: Ib71202801f8c72af2f22865899c93df1f3753fdd Reviewed-on: https://go-review.googlesource.com/46008 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Tom Bergan <[email protected]>
gopherbot
pushed a commit
to golang/net
that referenced
this issue
Nov 6, 2023
CL 46008 fixed golang/go#20704 by not recycling the responseWriterState if any previous Write call failed, as there could be outstanding goroutines referencing the responseWriterState memory. More recently, CL 467355 fixed a variant of the same issue by not referencing that memory after exiting the Write call. This fix supersedes the fix in CL 46008, as it is more general and does not require the caller to know whether any previous Write calls failed. This CL partially reverts CL 46008 just leaving the test case to ensure that golang/go#20704 does not regress. Change-Id: I18ea4d27420265a94cc7af21f1dffa3f7dc3bd34 Reviewed-on: https://go-review.googlesource.com/c/net/+/534315 TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Damien Neil <[email protected]> Reviewed-by: Damien Neil <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Run-TryBot: Quim Muntal <[email protected]> Commit-Queue: Damien Neil <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
FrozenDueToAge
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
It looks like the race is on the
net/http.(*http2responseWriterState).bw
field, which survives while the *http2responseWriterState value is passed through a sync.Pool. The goroutine running the handler does a write on that bufio.Writer, while another goroutine reads from it as part of an asynchronous frame write.http2responseWriter.handlerDone puts rws into the pool, but does not appear to check if there's an async write occurring.
What version of Go are you using (
go version
)?What operating system and processor architecture are you using (
go env
)?What did you do?
I ran the following program with the race detector: https://play.golang.org/p/Q9uoDKSNpf
What did you expect to see?
I expected no data races to be detected.
What did you see instead?
With both go1.8.3 and go1.9beta1, the race detector finds data races within net/http's HTTP/2 code (bundled from x/net/http2).
With
go1.8 build -gcflags="-trimpath=$PWD" -i -race -o /tmp/h2_race . && stress -p=1 /tmp/h2_race
, the race detector finds data races in about 1 in 5 runs of the program. Here's one from go1.8.3:And an example of the problem in go1.9beta1:
The text was updated successfully, but these errors were encountered: