Skip to content

Commit 4db13d7

Browse files
jellevandenhooffcagedmantis
authored andcommitted
[release-branch.go1.20] runtime: set raceignore to zero when starting a new goroutine
When reusing a g struct the runtime did not reset g.raceignore. Initialize raceignore to zero when initially setting racectx. A goroutine can end with a non-zero raceignore if it exits after calling runtime.RaceDisable without a matching runtime.RaceEnable. If that goroutine's g is later reused the race detector is in a weird state: the underlying g.racectx is active, yet g.raceignore is non-zero, and raceacquire/racerelease which check g.raceignore become no-ops. This causes the race detector to report races when there are none. For #60934 Fixes #60949 Change-Id: Ib8e412f11badbaf69a480f03740da70891f4093f Reviewed-on: https://go-review.googlesource.com/c/go/+/505055 Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Michael Knyszek <[email protected]> (cherry picked from commit 48dbb62) Reviewed-on: https://go-review.googlesource.com/c/go/+/505676 Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 08a58dd commit 4db13d7

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/runtime/proc.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4351,6 +4351,7 @@ func newproc1(fn *funcval, callergp *g, callerpc uintptr) *g {
43514351
pp.goidcache++
43524352
if raceenabled {
43534353
newg.racectx = racegostart(callerpc)
4354+
newg.raceignore = 0
43544355
if newg.labels != nil {
43554356
// See note in proflabel.go on labelSync's role in synchronizing
43564357
// with the reads in the signal handler.

src/runtime/race/testdata/mop_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,3 +2092,40 @@ func TestNoRaceTinyAlloc(t *testing.T) {
20922092
<-done
20932093
}
20942094
}
2095+
2096+
func TestNoRaceIssue60934(t *testing.T) {
2097+
// Test that runtime.RaceDisable state doesn't accidentally get applied to
2098+
// new goroutines.
2099+
2100+
// Create several goroutines that end after calling runtime.RaceDisable.
2101+
var wg sync.WaitGroup
2102+
ready := make(chan struct{})
2103+
wg.Add(32)
2104+
for i := 0; i < 32; i++ {
2105+
go func() {
2106+
<-ready // ensure we have multiple goroutines running at the same time
2107+
runtime.RaceDisable()
2108+
wg.Done()
2109+
}()
2110+
}
2111+
close(ready)
2112+
wg.Wait()
2113+
2114+
// Make sure race detector still works. If the runtime.RaceDisable state
2115+
// leaks, the happens-before edges here will be ignored and a race on x will
2116+
// be reported.
2117+
var x int
2118+
ch := make(chan struct{}, 0)
2119+
wg.Add(2)
2120+
go func() {
2121+
x = 1
2122+
ch <- struct{}{}
2123+
wg.Done()
2124+
}()
2125+
go func() {
2126+
<-ch
2127+
_ = x
2128+
wg.Done()
2129+
}()
2130+
wg.Wait()
2131+
}

0 commit comments

Comments
 (0)