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

runtime: data race on stack object when using arena on darwin arm64 #61835

Open
578559967 opened this issue Aug 8, 2023 · 5 comments
Open

runtime: data race on stack object when using arena on darwin arm64 #61835

578559967 opened this issue Aug 8, 2023 · 5 comments
Assignees
Labels
arch-arm64 compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. RaceDetector
Milestone

Comments

@578559967
Copy link

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

$ go version
go version go1.21rc4 darwin/arm64

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='arm64'
GOBIN=''
GOCACHE='/Users/r/Library/Caches/go-build'
GOENV='/Users/r/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE='catdb.io'
GOMODCACHE='/Users/r/go/pkg/mod'
GONOPROXY='catdb.io'
GONOSUMDB='catdb.io'
GOOS='darwin'
GOPATH='/Users/r/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/r/sdk/go1.21rc4'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/r/sdk/go1.21rc4/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21rc4'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/j_/rq9ph2cd3h50w468sgv34lwh0000gn/T/go-build3636825793=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOROOT/bin/go version: go version go1.21rc4 darwin/arm64
GOROOT/bin/go tool compile -V: compile version go1.21rc4
uname -v: Darwin Kernel Version 22.4.0: Mon Mar  6 20:59:28 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T6000
ProductName:		macOS
ProductVersion:		13.3.1
ProductVersionExtra:	(a)
BuildVersion:		22E772610a
lldb --version: lldb-1403.0.17.67
Apple Swift version 5.8.1 (swiftlang-5.8.0.124.5 clang-1403.0.22.11.100)

What did you do?

test7.go:

package main

import (
	"arena"
	"sync"
)

const N = 200
const M = 2000000

func run() {
	for {
		arn := arena.NewArena()
		var wg sync.WaitGroup
		for i := 0; i < 2000; i++ {
			wg.Add(1)
			go func(i int) {
				defer wg.Done()
				process(0)
			}(i % 15)
			if i%2 == 0 {
				arena.MakeSlice[*int](arn, M/8, M/8)
			} else {
				s := make([]*int, i)
				_ = s
			}
		}
		wg.Wait()
		arn.Free()
	}
}

//go:noinline
func fill(a *[N]int) {
	for i := range a {
		a[i] = i
	}
}

func process(k int) int {
	var a [N]int
	fill(&a)
	if k > 10 {
		return 0
	}
	return process(k + 1)
}

func main() {
	for i := 0; i < 10; i++ {
		go run()
	}
	run()
}

run with race:

GOEXPERIMENT=arenas  go1.21rc4 run -race test7.go

What did you expect to see?

No race.

What did you see instead?

==================
WARNING: DATA RACE
Write at 0x00e400013918 by goroutine 146912:
  main.fill()
      /Users/r/workspace/testcode/testarena/test7.go:36 +0x40
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:42 +0x44
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.run.func1()
      /Users/r/workspace/testcode/testarena/test7.go:19 +0x5c
  main.run.func2()
      /Users/r/workspace/testcode/testarena/test7.go:20 +0x44

Previous write at 0x00e400013918 by goroutine 146908:
  main.fill()
      /Users/r/workspace/testcode/testarena/test7.go:36 +0x40
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:42 +0x44
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.process()
      /Users/r/workspace/testcode/testarena/test7.go:46 +0x6c
  main.run.func1()
      /Users/r/workspace/testcode/testarena/test7.go:19 +0x5c
  main.run.func2()
      /Users/r/workspace/testcode/testarena/test7.go:20 +0x44

Goroutine 146912 (running) created at:
  main.run()
      /Users/r/workspace/testcode/testarena/test7.go:17 +0x1a8

Goroutine 146908 (finished) created at:
  main.run()
      /Users/r/workspace/testcode/testarena/test7.go:17 +0x1a8
==================
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Aug 8, 2023
@578559967
Copy link
Author

This race can also be reproduced on linux-arm64.

@mknyszek mknyszek changed the title runtime: data race on stack object when using arena on darwin arm64. runtime: data race on stack object when using arena on darwin arm64 Aug 8, 2023
@mknyszek
Copy link
Contributor

mknyszek commented Aug 8, 2023

arn can only be used by one goroutine at a time. The allocations produced by the arena can be accessed by multiple goroutines concurrently, but you can't call arena.MakeSlice for the same arena from multiple goroutines (unless you put a lock around it or otherwise ensure mutually exclusive access). This is documented here: https://cs.opensource.google/go/go/+/master:src/arena/arena.go;l=43?q=arena.go&ss=go%2Fgo.

We have no plans to lift this restriction in the near future.

@mknyszek mknyszek closed this as not planned Won't fix, can't repro, duplicate, stale Aug 8, 2023
@mknyszek mknyszek reopened this Aug 8, 2023
@mknyszek
Copy link
Contributor

mknyszek commented Aug 8, 2023

Oops, just kidding. Rereading your code I think I misunderstood. I'll take a closer look. Sorry about that.

@mknyszek mknyszek added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 8, 2023
@mknyszek mknyszek added this to the Backlog milestone Aug 8, 2023
@mknyszek
Copy link
Contributor

mknyszek commented Aug 8, 2023

OK, I suspect this is due to the fact that in raceenabled mode the user arena address space is more mixed in with the regular heap address space. It kind of looks like:

  1. Something is wrong with race detector tracking in the arena implementation.
  2. It's spilling over into a stack allocation that reuses the arena address space.

I'm surprised that stacks are being allocated in what was user arena address space, but maybe I'm misremembering or there's a bug. At the very least, I think I found a double racefree issue? Maybe that's it?

@mknyszek mknyszek self-assigned this Aug 8, 2023
@mknyszek mknyszek modified the milestones: Backlog, Go1.22 Aug 8, 2023
@578559967
Copy link
Author

OK, I suspect this is due to the fact that in raceenabled mode the user arena address space is more mixed in with the regular heap address space. It kind of looks like:

  1. Something is wrong with race detector tracking in the arena implementation.
  2. It's spilling over into a stack allocation that reuses the arena address space.

I'm surprised that stacks are being allocated in what was user arena address space, but maybe I'm misremembering or there's a bug. At the very least, I think I found a double racefree issue? Maybe that's it?

I have printed the address space when allocating arena chunk and stack. I found that the user arena address space is always reused for arena and never recycled for stack or heap. The address of the race data is never been in an arena chunk.

I also noticed the double racefree in func freeUserArenaChunk() and func (s *mspan) setUserArenaChunkToFault(). And after I removed the racefree in func (s *mspan) setUserArenaChunkToFault()`, this race just happened again. So I don't think it is the root cause.

By the way, I haven't see racefree in func stackfree(). I don't know how this works that normal code(without arena) never reports races of stack object. I have tried to add racefree in func stackfree(), but the race still exists.

@mknyszek mknyszek modified the milestones: Go1.22, Backlog Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-arm64 compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. RaceDetector
Projects
Development

No branches or pull requests

3 participants