go: time: racy Timer access should either work or throw, not panic
2020-02-21T20:22:19-13d73b2/linux-arm
panic: runtime error: racy use of timers
panic: err must be non-nil
goroutine 3372 [running]:
net/http.(*http2pipe).closeWithError(0xd6f774, 0xd6f7a8, 0x0, 0x0, 0x0)
/workdir/go/src/net/http/h2_bundle.go:3558 +0x210
net/http.(*http2pipe).CloseWithError(...)
/workdir/go/src/net/http/h2_bundle.go:3545
net/http.(*http2clientConnReadLoop).cleanup(0xc43fd4)
/workdir/go/src/net/http/h2_bundle.go:8228 +0x21c
panic(0x467b60, 0x580c18)
/workdir/go/src/runtime/panic.go:967 +0x118
time.stopTimer(0x10c9e84, 0x10a9ca8)
/workdir/go/src/runtime/time.go:224 +0x1c
time.(*Timer).Stop(...)
/workdir/go/src/time/sleep.go:78
net/http.http2bodyWriterState.on100(0xd6f760, 0x10c9e80, 0x10a9c80, 0xefc780, 0x10c9e40, 0x3b9aca00, 0x0)
/workdir/go/src/net/http/h2_bundle.go:9057 +0x38
net/http.(*http2clientConnReadLoop).handleResponse(0xc43fd4, 0xd6f760, 0xefc800, 0xd6f760, 0x58a650, 0x2cdc78)
/workdir/go/src/net/http/h2_bundle.go:8433 +0x2fc
net/http.(*http2clientConnReadLoop).processHeaders(0xc43fd4, 0xefc800, 0x0, 0x0)
/workdir/go/src/net/http/h2_bundle.go:8355 +0x14c
net/http.(*http2clientConnReadLoop).run(0xc43fd4, 0x0, 0x0)
/workdir/go/src/net/http/h2_bundle.go:8277 +0x648
net/http.(*http2ClientConn).readLoop(0xdb2000)
/workdir/go/src/net/http/h2_bundle.go:8174 +0x60
created by net/http.(*http2Transport).newClientConn
/workdir/go/src/net/http/h2_bundle.go:7174 +0x538
FAIL net/http 6.612s
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 21 (15 by maintainers)
This panic was introduced in Go 1.11, so I guess it is not a Go 1.14 release blocker. Still think it should probably either be fixed or changed to a runtime.throw. The unexpected panic is problematic (see the nested panic in the trace above). Stop should either work or crash the program, not panic.
Just to be clear, the problem was not introduced in 1.11. The program above also fails with 1.10. What happened in 1.11 was that the problem changed from a throw saying “fatal error: panic holding locks” to a panic saying “runtime error: racy use of timers”. Changing from a throw to a panic was a mistake on my part. But changing from “panic holding locks” to “racy use of timers” was not.
Before 1.10 the problem still exists but is harder to reproduce. What changed in 1.10 was that we switched to many different timer buckets. With fewer timers in each bucket it’s easier to create a case in which
siftupTimer
gets an index out of range.In any case we can do better with the new timers.