Skip to content

runtime/race: false positive with closed channels in default select (go1.14beta1) #36714

@zeebo

Description

@zeebo

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

go1.14beta1

$ go version
go version devel +a5bfd9da1d Tue Dec 17 14:59:30 2019 +0000 linux/amd64

Does this issue reproduce with the latest release?

No, go1.13.6 does not have the problem.

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/jeff/.cache/go-build"
GOENV="/home/jeff/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/jeff/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org"
GOROOT="/home/jeff/gotip"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/jeff/gotip/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/jeff/tmp/raceissue/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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build491500605=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://play.golang.org/p/aJkZKenyXHu

package main

func main() {
	for {
		var loc int
		var write = make(chan struct{})
		var read = make(chan struct{})

		go func() {
			select {
			case <-write:
				_ = loc
			default:
			}
			close(read)
		}()

		go func() {
			loc = 1
			close(write)
		}()

		<-read
	}
}

I ran the above code with GORACE="halt_on_error=1" go run -race *.go

What did you expect to see?

No error.

What did you see instead?

==================
WARNING: DATA RACE
Read at 0x00c000112000 by goroutine 6:
  main.main.func1()
      /home/jeff/tmp/raceissue/race.go:12 +0x73

Previous write at 0x00c000112000 by goroutine 7:
  main.main.func2()
      /home/jeff/tmp/raceissue/race.go:19 +0x38

Goroutine 6 (running) created at:
  main.main()
      /home/jeff/tmp/raceissue/race.go:9 +0xd4

Goroutine 7 (finished) created at:
  main.main()
      /home/jeff/tmp/raceissue/race.go:18 +0x100
==================
exit status 66

I did a git bisect between go1.13.6 and go1.14beta1 and it pointed at e1446d9 which seemed to be a great likely candidate. After finding that, I found that the issue does not present itself if the write channel in the example is sent on instead of closed, or if there is not a default case in the select. Additionally, running on go1.14beta1 with that commit reverted also causes the example to succeed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.release-blocker

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions