Skip to content

runtime: race condition raised with parallel tests, panic(nil) and -race #64649

@dolmen

Description

@dolmen

Go version

go version go1.21.5 darwin/arm64

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

- Local (Apple M2)
- GitHub Actions (x86)

What did you do?

I have a testsuite for my github.com/dolmen-go/rendezvous package.

$ git clone https://github.com/dolmen-go/rendezvous.git
$ cd rendezvous
$ git checkout 44e68d01a216b3755c9ba5dc75835074c3e5e866
$ go version
go version go1.21.5 darwin/arm64
$ go test -v -race -run 'Test(One|Two)' "-gcflags=all=-trimpath=$(go env GOPATH)" github.com/dolmen-go/rendezvous
=== RUN   TestOne
=== PAUSE TestOne
=== RUN   TestTwo
=== PAUSE TestTwo
=== CONT  TestOne
=== CONT  TestTwo
==================
WARNING: DATA RACE
Read at 0x00c000076560 by goroutine 14:
  internal/godebug.(*Setting).IncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/internal/godebug/godebug.go:102 +0x58
  internal/godebug.(*Setting).IncNonDefault-fm()
      <autogenerated>:1 +0x34
  runtime.(*godebugInc).IncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/runtime/runtime.go:111 +0xd0
  github.com/dolmen-go/rendezvous.WaitAll.func1()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:56 +0xec
  github.com/dolmen-go/rendezvous.WaitAll.func2()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:57 +0x44

Previous write at 0x00c000076560 by goroutine 12:
  internal/godebug.New()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/internal/godebug/godebug.go:74 +0x40
  internal/godebug.newIncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/internal/godebug/godebug.go:203 +0x28
  runtime.(*godebugInc).IncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/runtime/runtime.go:108 +0x84
  github.com/dolmen-go/rendezvous.WaitAll.func1()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:56 +0xec
  github.com/dolmen-go/rendezvous.WaitAll.func2()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:57 +0x44

Goroutine 14 (running) created at:
  github.com/dolmen-go/rendezvous.WaitAll()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:47 +0x210
  github.com/dolmen-go/rendezvous_test.TestTwo()
      src/github.com/dolmen-go/rendezvous/rendezvous_test.go:118 +0xe4
  testing.tRunner()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/testing/testing.go:1595 +0x1b0
  testing.(*T).Run.func1()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/testing/testing.go:1648 +0x40

Goroutine 12 (running) created at:
  github.com/dolmen-go/rendezvous.WaitAll()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:47 +0x210
  github.com/dolmen-go/rendezvous_test.TestOne()
      src/github.com/dolmen-go/rendezvous/rendezvous_test.go:104 +0x180
  testing.tRunner()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/testing/testing.go:1595 +0x1b0
  testing.(*T).Run.func1()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/testing/testing.go:1648 +0x40
==================
=== NAME  TestOne
    testing.go:1465: race detected during execution of test
--- FAIL: TestOne (0.00s)
=== NAME  TestTwo
    testing.go:1465: race detected during execution of test
--- FAIL: TestTwo (0.00s)
FAIL
exit status 1
FAIL	github.com/dolmen-go/rendezvous	0.104s

Some characteristics that might be relevant:

  • The rendezvous package launches goroutines in its tests.
  • The rendezvous testsuite uses parallel testing at top testing level:
func TestOne(t *testing.T) {
        t.Parallel()
        // ...
}

func TestTwo(t *testing.T) {
        t.Parallel()
        // ...
}

This issue is also visible on GitHub Actions: https://github.com/dolmen-go/rendezvous/actions/runs/7147035848/job/19465833264#step:4:32

What did you expect to see?

Test success like with previous Go versions.

What did you see instead?

Race condition in runtime:

WARNING: DATA RACE
Read at 0x00c000076560 by goroutine 14:
  internal/godebug.(*Setting).IncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/internal/godebug/godebug.go:102 +0x58
  internal/godebug.(*Setting).IncNonDefault-fm()
      <autogenerated>:1 +0x34
  runtime.(*godebugInc).IncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/runtime/runtime.go:111 +0xd0
  github.com/dolmen-go/rendezvous.WaitAll.func1()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:56 +0xec
  github.com/dolmen-go/rendezvous.WaitAll.func2()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:57 +0x44

Previous write at 0x00c000076560 by goroutine 12:
  internal/godebug.New()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/internal/godebug/godebug.go:74 +0x40
  internal/godebug.newIncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/internal/godebug/godebug.go:203 +0x28
  runtime.(*godebugInc).IncNonDefault()
      /opt/homebrew/Cellar/go/1.21.5/libexec/src/runtime/runtime.go:108 +0x84
  github.com/dolmen-go/rendezvous.WaitAll.func1()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:56 +0xec
  github.com/dolmen-go/rendezvous.WaitAll.func2()
      src/github.com/dolmen-go/rendezvous/rendezvous.go:57 +0x44

Link to runtime source: https://github.com/golang/go/blob/go1.21.5/src/runtime/runtime.go#L97

A comment says:

		// If other goroutines are racing here, no big deal. One will win,
		// and all the inc functions will be using the same underlying
		// *godebug.Setting.

If this is related, I think this is "big deal" as running go test -race in CI is quite common. (Calling t.Parallel() from top level tests is not so common, this is unfortunate, and this issue blocks from pushing for it)

Metadata

Metadata

Assignees

Labels

FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.RaceDetectorcompiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions