Skip to content

runtime: apparent false-positive race report for a buffered channel after CL 220419 #42598

@bcmills

Description

@bcmills

I got the following race report on CL 258758.

(https://storage.googleapis.com/go-build-log/04d98a9c/linux-amd64-race_596e00e8.log)

--- FAIL: TestScript (0.11s)
    --- FAIL: TestScript/mod_retract (0.34s)
        script_test.go:211: 
            # Populate go.sum. (0.087s)
            # 'go list pkg' does not report an error when a retracted version is used. (0.069s)
            # Nor does 'go build'. (0.000s)
            # Neither 'go list' nor 'go build' should download go.mod from the version
            # that would list retractions. (0.000s)
            # Importing a package from a module with a retracted latest version will
            # select the latest non-retracted version. (0.175s)
            > go get -d ./use_self_prev
            [stderr]
            go: downloading example.com v1.0.0
            go: downloading example.com/retract/self/prev v1.1.0
            go: downloading example.com/retract v1.1.0
            ==================
            WARNING: DATA RACE
            Read at 0x00c0002c0ce8 by main goroutine:
              cmd/go/internal/modget.reportRetractions()
                  /workdir/go/src/cmd/go/internal/modget/get.go:550 +0x224
              cmd/go/internal/modget.runGet()
                  /workdir/go/src/cmd/go/internal/modget/get.go:490 +0x931
              main.main()
                  /workdir/go/src/cmd/go/main.go:195 +0xb94
            
            Previous write at 0x00c0002c0ce8 by goroutine 76:
              cmd/go/internal/modload.addRetraction()
                  /workdir/go/src/cmd/go/internal/modload/build.go:132 +0x424
              cmd/go/internal/modload.ListModules.func1.1()
                  /workdir/go/src/cmd/go/internal/modload/list.go:40 +0x84
            
            Goroutine 76 (finished) created at:
              cmd/go/internal/modload.ListModules.func1()
                  /workdir/go/src/cmd/go/internal/modload/list.go:32 +0xe4
              cmd/go/internal/modload.ListModules()
                  /workdir/go/src/cmd/go/internal/modload/list.go:46 +0x1fa
              cmd/go/internal/modget.reportRetractions()
                  /workdir/go/src/cmd/go/internal/modget/get.go:547 +0x184
              cmd/go/internal/modget.runGet()
                  /workdir/go/src/cmd/go/internal/modget/get.go:490 +0x931
              main.main()
                  /workdir/go/src/cmd/go/main.go:195 +0xb94
            ==================
            ==================
            WARNING: DATA RACE
            Read at 0x00c000058ac0 by main goroutine:
              cmd/go/internal/modget.reportRetractions()
                  /workdir/go/src/cmd/go/internal/modget/get.go:556 +0x2b9
              cmd/go/internal/modget.runGet()
                  /workdir/go/src/cmd/go/internal/modget/get.go:490 +0x931
              main.main()
                  /workdir/go/src/cmd/go/main.go:195 +0xb94
            
            Previous write at 0x00c000058ac0 by goroutine 76:
              cmd/go/internal/modload.checkRetractions()
                  /workdir/go/src/cmd/go/internal/modload/modfile.go:163 +0x4a4
              cmd/go/internal/modload.addRetraction()
                  /workdir/go/src/cmd/go/internal/modload/build.go:126 +0x104
              cmd/go/internal/modload.ListModules.func1.1()
                  /workdir/go/src/cmd/go/internal/modload/list.go:40 +0x84
            
            Goroutine 76 (finished) created at:
              cmd/go/internal/modload.ListModules.func1()
                  /workdir/go/src/cmd/go/internal/modload/list.go:32 +0xe4
              cmd/go/internal/modload.ListModules()
                  /workdir/go/src/cmd/go/internal/modload/list.go:46 +0x1fa
              cmd/go/internal/modget.reportRetractions()
                  /workdir/go/src/cmd/go/internal/modget/get.go:547 +0x184
              cmd/go/internal/modget.runGet()
                  /workdir/go/src/cmd/go/internal/modget/get.go:490 +0x931
              main.main()
                  /workdir/go/src/cmd/go/main.go:195 +0xb94
            ==================
            go: warning: example.com/retract@v1.0.0-bad is retracted: bad
            go: run 'go get example.com/retract@latest' to switch to the latest unretracted version
            Found 2 data race(s)
            [exit status 66]
            FAIL: testdata/script/mod_retract.txt:23: unexpected command failure
            
FAIL
FAIL	cmd/go	151.822s

The reported race is for a function that uses an N-buffered channel as a semaphore. The function sends to the channel (from the main goroutine) to acquire a semaphore token, and receives from the channel (in a background goroutine) to release the token. Before the function returns, it sends N additional tokens to the channel to ensure that all of the background goroutines have finished.

I believe that this pattern is explicitly covered by the memory model:

The kth receive on a channel with capacity C happens before the k+Cth send from that channel completes.

This is the first race we've seen reported for this code, and the timing w.r.t. CL 220419, which changes the semantics of channels under the race detector, seems suspicious to me.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions