From 879e3cb5f787ed56bee2f5f4d92fd013a9b47b21 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Tue, 26 Aug 2025 13:26:57 -0700 Subject: [PATCH] [release-branch.go1.25] runtime: lock mheap_.speciallock when allocating synctest specials Avoid racing use of mheap_.specialBubbleAlloc. For #75134 Fixes #75347 Change-Id: I0c9140c18d2bca1e1c3387cd81230f0e8c9ac23e Reviewed-on: https://go-review.googlesource.com/c/go/+/699255 Reviewed-by: Michael Knyszek LUCI-TryBot-Result: Go LUCI (cherry picked from commit 5dcedd65504cc9cadc9a5ea8bc3af51a26eec704) Reviewed-on: https://go-review.googlesource.com/c/go/+/701797 Reviewed-by: Damien Neil Reviewed-by: Mark Freeman Auto-Submit: Michael Knyszek --- src/internal/synctest/synctest_test.go | 22 ++++++++++++++++++++++ src/runtime/synctest.go | 2 ++ 2 files changed, 24 insertions(+) diff --git a/src/internal/synctest/synctest_test.go b/src/internal/synctest/synctest_test.go index 307eee62e2..73a0a1c453 100644 --- a/src/internal/synctest/synctest_test.go +++ b/src/internal/synctest/synctest_test.go @@ -779,6 +779,28 @@ func TestWaitGroupHeapAllocated(t *testing.T) { }) } +// Issue #75134: Many racing bubble associations. +func TestWaitGroupManyBubbles(t *testing.T) { + var wg sync.WaitGroup + for range 100 { + wg.Go(func() { + synctest.Run(func() { + cancelc := make(chan struct{}) + var wg2 sync.WaitGroup + for range 100 { + wg2.Go(func() { + <-cancelc + }) + } + synctest.Wait() + close(cancelc) + wg2.Wait() + }) + }) + } + wg.Wait() +} + func TestHappensBefore(t *testing.T) { // Use two parallel goroutines accessing different vars to ensure that // we correctly account for multiple goroutines in the bubble. diff --git a/src/runtime/synctest.go b/src/runtime/synctest.go index 16af1209b4..529f69fd93 100644 --- a/src/runtime/synctest.go +++ b/src/runtime/synctest.go @@ -410,7 +410,9 @@ func getOrSetBubbleSpecial(p unsafe.Pointer, bubbleid uint64, add bool) (assoc i } else if add { // p is not associated with a bubble, // and we've been asked to add an association. + lock(&mheap_.speciallock) s := (*specialBubble)(mheap_.specialBubbleAlloc.alloc()) + unlock(&mheap_.speciallock) s.bubbleid = bubbleid s.special.kind = _KindSpecialBubble s.special.offset = offset -- 2.52.0