You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have an integration test for an ACME extension ([1]) that instantiate
Pebble. I noticed that I would sometimes get test failures under `go
test -race` like this:
```
==================
WARNING: DATA RACE
Write at 0x00c00026cd80 by goroutine 143:
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).orderForDisplay.func2()
/home/timg/source/pebble/wfe/wfe.go:1876 +0x255
math/rand.(*Rand).Shuffle()
/usr/local/go/src/math/rand/rand.go:265 +0x96
math/rand.Shuffle()
/usr/local/go/src/math/rand/rand.go:470 +0x38
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).orderForDisplay()
/home/timg/source/pebble/wfe/wfe.go:1875 +0x204
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).Order()
/home/timg/source/pebble/wfe/wfe.go:2021 +0x5ed
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).Order-fm()
<autogenerated>:1 +0x69
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).HandleFunc.func1()
/home/timg/source/pebble/wfe/wfe.go:306 +0xa09
github.com/letsencrypt/pebble/v2/wfe.wfeHandlerFunc.ServeHTTP()
/home/timg/source/pebble/wfe/wfe.go:146 +0x56
github.com/letsencrypt/pebble/v2/wfe.(*topHandler).ServeHTTP()
/home/timg/source/pebble/wfe/wfe.go:158 +0x5b
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).HandleFunc.StripPrefix.func2()
/usr/local/go/src/net/http/server.go:2282 +0x471
net/http.HandlerFunc.ServeHTTP()
/usr/local/go/src/net/http/server.go:2220 +0x47
net/http.(*ServeMux).ServeHTTP()
/usr/local/go/src/net/http/server.go:2747 +0x255
net/http.serverHandler.ServeHTTP()
/usr/local/go/src/net/http/server.go:3210 +0x2a1
net/http.(*conn).serve()
/usr/local/go/src/net/http/server.go:2092 +0x12a4
net/http.(*Server).Serve.gowrap3()
/usr/local/go/src/net/http/server.go:3360 +0x4f
Previous read at 0x00c00026cd80 by goroutine 274:
github.com/letsencrypt/pebble/v2/ca.(*CAImpl).CompleteOrder()
/home/timg/source/pebble/ca/ca.go:448 +0x76f
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).FinalizeOrder.func1()
/home/timg/source/pebble/wfe/wfe.go:2215 +0x8d
Goroutine 143 (running) created at:
net/http.(*Server).Serve()
/usr/local/go/src/net/http/server.go:3360 +0x8ec
net/http.(*Server).ServeTLS()
/usr/local/go/src/net/http/server.go:3401 +0x706
net/http.ServeTLS()
/usr/local/go/src/net/http/server.go:2875 +0x269
github.com/tgeoghegan/oidf-box/test.setupPebble.func1()
/home/timg/source/oidf-box/test/harness.go:297 +0x19c
Goroutine 274 (running) created at:
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).FinalizeOrder()
/home/timg/source/pebble/wfe/wfe.go:2214 +0x2fa4
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).FinalizeOrder-fm()
<autogenerated>:1 +0x69
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).HandleFunc.func1()
/home/timg/source/pebble/wfe/wfe.go:306 +0xa09
github.com/letsencrypt/pebble/v2/wfe.wfeHandlerFunc.ServeHTTP()
/home/timg/source/pebble/wfe/wfe.go:146 +0x56
github.com/letsencrypt/pebble/v2/wfe.(*topHandler).ServeHTTP()
/home/timg/source/pebble/wfe/wfe.go:158 +0x5b
github.com/letsencrypt/pebble/v2/wfe.(*WebFrontEndImpl).HandleFunc.StripPrefix.func2()
/usr/local/go/src/net/http/server.go:2282 +0x471
net/http.HandlerFunc.ServeHTTP()
/usr/local/go/src/net/http/server.go:2220 +0x47
net/http.(*ServeMux).ServeHTTP()
/usr/local/go/src/net/http/server.go:2747 +0x255
net/http.serverHandler.ServeHTTP()
/usr/local/go/src/net/http/server.go:3210 +0x2a1
net/http.(*conn).serve()
/usr/local/go/src/net/http/server.go:2092 +0x12a4
net/http.(*Server).Serve.gowrap3()
/usr/local/go/src/net/http/server.go:3360 +0x4f
==================
```
What's happening is that `CAImpl.CompleteOrder` is fetching an `Order`
from the "database" (which is in-memory) and iterating over the
identifiers therein. `WebFrontEndImpl.orderForDisplay` fetches an
`Order` from the database and then wants to construct a shuffled version
of the order to return to the client to ensure nobody makes assumptions
about the layout of these objects.
`orderForDisplay` tries to take a copy of the `acme.Order`, but
evidently that copies *pointers* to the `[]acme.Identifier Identifiers`
and `[]string Authorizations` fields, which means shuffling them in the
"copy" shuffles them in the DB object and makes the race detector
unhappy.
[1]: https://github.com/tgeoghegan/oidf-box
0 commit comments