Navigation Menu

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

syscall: NewCallback triggers data race on Windows when used from different goroutine #50249

Closed
JohanKnutzen opened this issue Dec 17, 2021 · 8 comments
Assignees
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Milestone

Comments

@JohanKnutzen
Copy link

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

$ go version
go version go1.17.4 windows/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
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\knutz\AppData\Local\go-build
set GOENV=C:\Users\knutz\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\knutz\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\knutz\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.17.4
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\knutz\AppData\Local\Temp\go-build2788134738=/tmp/go-build -gno-record-gcc-switches

What did you do?

package main

import (
	"syscall"
)

func foo() {
	syscall.NewCallback(func(callerContext uintptr, iface uintptr, notificationType uint32) uintptr {
		return 0
	})
}

func main() {
	go foo()
	foo()
}

Built and run using:
go build -race && ./main.exe

What did you expect to see?

Nothing

What did you see instead?

WARNING: DATA RACE
Read at 0x00c000028000 by goroutine 6:
  runtime.mapaccess2()
      C:/Program Files/Go/src/runtime/map.go:452 +0x0
  syscall.compileCallback()
      C:/Program Files/Go/src/runtime/syscall_windows.go:308 +0x244

Previous write at 0x00c000028000 by main goroutine:
  runtime.mapassign()
      C:/Program Files/Go/src/runtime/map.go:571 +0x0
  syscall.compileCallback()
      C:/Program Files/Go/src/runtime/syscall_windows.go:324 +0x392
  main.main()
      C:/code/fd/hack/compile_syscall_race/main.go:15 +0x30

Goroutine 6 (running) created at:
  main.main()
      C:/code/fd/hack/compile_syscall_race/main.go:14 +0x2b
==================
Found 1 data race(s)```

@randall77
Copy link
Contributor

Those map accesses are guarded by a lock. Not sure why the race detector would report on them.

@JohanKnutzen
Copy link
Author

@randall77 From reviewing the code, that seems to be the case. Perhaps this is a bug in the race detector? More specifically when run on Windows

@cherrymui
Copy link
Member

The race detector probably doesn't know about the lock. It seems runtime lock does not inform the race detector about the edge (unlike locks in the sync package). (Normally it is fine as the runtime is not race-instrumented. But that code uses a map and mapassign/mapaccess have explicit race calls).

@dmitshur dmitshur added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows labels Dec 21, 2021
@prattmic prattmic self-assigned this Jun 28, 2022
@prattmic prattmic added this to the Go1.19 milestone Jun 28, 2022
@prattmic prattmic added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Jun 28, 2022
@gopherbot
Copy link

Change https://go.dev/cl/414518 mentions this issue: runtime: add race annotations to cbs.lock

@prattmic
Copy link
Member

@gopherbot please backport to 1.17 and 1.18. This triggers a false positive in the race detector for programs calling syscall.NewCallback from multiple goroutines. There is a workaround: use a single global lock around all calls to syscall.NewCallback in the program. However, that is quite invasive and difficult for complex code.

@gopherbot
Copy link

Backport issue(s) opened: #53612 (for 1.17), #53613 (for 1.18).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

@gopherbot
Copy link

Change https://go.dev/cl/415197 mentions this issue: [release-branch.go1.17] runtime: add race annotations to cbs.lock

@gopherbot
Copy link

Change https://go.dev/cl/415198 mentions this issue: [release-branch.go1.18] runtime: add race annotations to cbs.lock

gopherbot pushed a commit that referenced this issue Jul 6, 2022
cbs.lock protects a map. The map implementation is race instrumented
regardless of which package is it called from.

lock/unlock are not automatically race instrumented, so we can trigger
race false positives without manually annotating our lock acquire and
release.

compileCallback is used during initialization before the P is available,
at which point raceacquire will crash during a racecallback to get the
race proc. Thus we skip instrumentation until scheduler initialization
is complete.

Fixes #53613.
For #50249.

Change-Id: Ie49227c9e9210ffbf0aee65f86f2b7b6a2f64638
Reviewed-on: https://go-review.googlesource.com/c/go/+/414518
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
(cherry picked from commit 20760cf)
Reviewed-on: https://go-review.googlesource.com/c/go/+/415198
Run-TryBot: Heschi Kreinick <heschi@google.com>
gopherbot pushed a commit that referenced this issue Jul 6, 2022
cbs.lock protects a map. The map implementation is race instrumented
regardless of which package is it called from.

lock/unlock are not automatically race instrumented, so we can trigger
race false positives without manually annotating our lock acquire and
release.

compileCallback is used during initialization before the P is available,
at which point raceacquire will crash during a racecallback to get the
race proc. Thus we skip instrumentation until scheduler initialization
is complete.

Fixes #53612.
For #50249.

Change-Id: Ie49227c9e9210ffbf0aee65f86f2b7b6a2f64638
Reviewed-on: https://go-review.googlesource.com/c/go/+/414518
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
(cherry picked from commit 20760cf)
Reviewed-on: https://go-review.googlesource.com/c/go/+/415197
bradfitz pushed a commit to tailscale/go that referenced this issue Jul 14, 2022
cbs.lock protects a map. The map implementation is race instrumented
regardless of which package is it called from.

lock/unlock are not automatically race instrumented, so we can trigger
race false positives without manually annotating our lock acquire and
release.

compileCallback is used during initialization before the P is available,
at which point raceacquire will crash during a racecallback to get the
race proc. Thus we skip instrumentation until scheduler initialization
is complete.

Fixes golang#53613.
For golang#50249.

Change-Id: Ie49227c9e9210ffbf0aee65f86f2b7b6a2f64638
Reviewed-on: https://go-review.googlesource.com/c/go/+/414518
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
(cherry picked from commit 20760cf)
Reviewed-on: https://go-review.googlesource.com/c/go/+/415198
Run-TryBot: Heschi Kreinick <heschi@google.com>
jproberts pushed a commit to jproberts/go that referenced this issue Aug 10, 2022
cbs.lock protects a map. The map implementation is race instrumented
regardless of which package is it called from.

lock/unlock are not automatically race instrumented, so we can trigger
race false positives without manually annotating our lock acquire and
release.

compileCallback is used during initialization before the P is available,
at which point raceacquire will crash during a racecallback to get the
race proc. Thus we skip instrumentation until scheduler initialization
is complete.

Fixes golang#50249.

Change-Id: Ie49227c9e9210ffbf0aee65f86f2b7b6a2f64638
Reviewed-on: https://go-review.googlesource.com/c/go/+/414518
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
@golang golang locked and limited conversation to collaborators Jun 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Projects
None yet
Development

No branches or pull requests

7 participants
@JohanKnutzen @prattmic @dmitshur @randall77 @gopherbot @cherrymui and others