runtime: avoid concurrent use of synctest timer race context.

When running a timer in a synctest bubble, create a temporary
race context for the operation. We can't use the bubble timer's
context, because multiple timers can execute simultaneously within
a bubble.

Fixes #76691

Change-Id: If862dd63333c5b3b2e75d44a078acd0e9da77a8f
Reviewed-on: https://go-review.googlesource.com/c/go/+/753200
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Commit-Queue: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
Manu Cupcic 2026-03-06 17:09:49 +01:00 committed by Gopher Robot
parent 15b9fc2659
commit 784ea961a4
2 changed files with 17 additions and 12 deletions

View file

@ -1126,13 +1126,7 @@ func (t *timer) unlockAndRun(now int64, bubble *synctestBubble) {
// Note that we are running on a system stack,
// so there is no chance of getg().m being reassigned
// out from under us while this function executes.
gp := getg()
var tsLocal *timers
if bubble == nil {
tsLocal = &gp.m.p.ptr().timers
} else {
tsLocal = &bubble.timers
}
tsLocal := &getg().m.p.ptr().timers
if tsLocal.raceCtx == 0 {
tsLocal.raceCtx = racegostart(abi.FuncPCABIInternal((*timers).run) + sys.PCQuantum)
}
@ -1184,11 +1178,7 @@ func (t *timer) unlockAndRun(now int64, bubble *synctestBubble) {
if gp.racectx != 0 {
throw("unexpected racectx")
}
if bubble == nil {
gp.racectx = gp.m.p.ptr().timers.raceCtx
} else {
gp.racectx = bubble.timers.raceCtx
}
gp.racectx = gp.m.p.ptr().timers.raceCtx
}
if ts != nil {

View file

@ -188,3 +188,18 @@ func TestNow(t *testing.T) {
}
})
}
func TestSynctestTimerRaceCtxCrash(t *testing.T) {
for range 20 {
t.Run("", func(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
for range 100 {
time.AfterFunc(1*time.Second, func() {
time.AfterFunc(0, func() {})
})
}
time.Sleep(2 * time.Second)
})
})
}
}