Skip to content
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

Concurrent calls to errors.As results in a data race #38293

Closed
yarikbratashchuk opened this issue Apr 7, 2020 · 2 comments
Closed

Concurrent calls to errors.As results in a data race #38293

yarikbratashchuk opened this issue Apr 7, 2020 · 2 comments

Comments

@yarikbratashchuk
Copy link

yarikbratashchuk commented Apr 7, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.1 darwin/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/yarik/Library/Caches/go-build"
GOENV="/Users/yarik/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY="github.com/uploadcare/common-go"
GONOSUMDB="github.com/uploadcare/common-go"
GOOS="darwin"
GOPATH="/Users/yarik/go"
GOPRIVATE="github.com/uploadcare/common-go"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/yarik/work/uploadcare/webhook/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/m_/z4_ls1zd2bdd3z1846w1l8sw0000gn/T/go-build030379024=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Concurrently calling errors.As:
https://play.golang.org/p/7FQegBPdSkq

What did you expect to see?

No data race

What did you see instead?

Data race:

==================
WARNING: DATA RACE
Write at 0x00000135ba10 by goroutine 10:
  reflect.typedmemmove()
      /usr/local/go/src/runtime/mbarrier.go:177 +0x0
  internal/reflectlite.typedmemmove()
      /usr/local/go/src/runtime/mbarrier.go:191 +0x3e
  errors.As()
      /usr/local/go/src/errors/wrap.go:92 +0x38f
  github.com/yarikbratashchuk/datarace.fireDataRace()
      /Users/yarik/Desktop/main.go:20 +0x6e

Previous write at 0x00000135ba10 by goroutine 8:
  reflect.typedmemmove()
      /usr/local/go/src/runtime/mbarrier.go:177 +0x0
  internal/reflectlite.typedmemmove()
      /usr/local/go/src/runtime/mbarrier.go:191 +0x3e
  errors.As()
      /usr/local/go/src/errors/wrap.go:92 +0x38f
  github.com/yarikbratashchuk/datarace.fireDataRace()
      /Users/yarik/Desktop/main.go:20 +0x6e

Goroutine 10 (running) created at:
  github.com/yarikbratashchuk/datarace.test()
      /Users/yarik/Desktop/main.go:15 +0x4b
  github.com/yarikbratashchuk/datarace.TestMain()
      /Users/yarik/Desktop/main_test.go:8 +0x2f
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:992 +0x1eb

Goroutine 8 (finished) created at:
  github.com/yarikbratashchuk/datarace.test()
      /Users/yarik/Desktop/main.go:15 +0x4b
  github.com/yarikbratashchuk/datarace.TestMain()
      /Users/yarik/Desktop/main_test.go:8 +0x2f
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:992 +0x1eb
==================
    TestMain: testing.go:906: race detected during execution of test
--- FAIL: TestMain (0.01s)
@cespare
Copy link
Contributor

cespare commented Apr 7, 2020

That's expected. The second argument to errors.As, target, is mutated by the function. You wouldn't call it with a global value like context.DeadlineExceeded; you'd call it on a local error value of a particular type. An example from the errors documentation is:

var perr *os.PathError
if errors.As(err, &perr) {
	fmt.Println(perr.Path)
}

If you want to check whether you have an error that matches context.DeadlineExceeded, you'd use errors.Is, not errors.As:

if errors.Is(err, context.DeadlineExceeded) {

playground

@cespare cespare closed this as completed Apr 7, 2020
@yarikbratashchuk
Copy link
Author

Got it,
much thanks

@golang golang locked and limited conversation to collaborators Apr 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants