aboutsummaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2025-06-05 13:47:06 -0700
committerGopher Robot <gobot@golang.org>2025-06-10 15:02:26 -0700
commit4f86f2267167a63b673c4a2a2994e008b32c90ea (patch)
tree24dd8afd3e0e54897f199a95a151ccd5be83fab7 /src/sync
parent773701a853a3105696c59c2b92b2eff35e0e055b (diff)
downloadgo-4f86f2267167a63b673c4a2a2994e008b32c90ea.tar.xz
testing/synctest, runtime: avoid panic when using linker-alloc WG from bubble
We associate WaitGroups with synctest bubbles by attaching a special to the WaitGroup. It is not possible to attach a special to a linker-allocated value, such as: var wg sync.WaitGroup Avoid panicking when accessing a linker-allocated WaitGroup from a bubble. We have no way to associate these WaitGroups with a bubble, so just treat them as always unbubbled. This is probably fine, since the WaitGroup was always created outside the bubble in this case. Fixes #74005 Change-Id: Ic71514b0b8d0cecd62e45cc929ffcbeb16f54a55 Reviewed-on: https://go-review.googlesource.com/c/go/+/679695 Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/sync')
-rw-r--r--src/sync/waitgroup.go12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/sync/waitgroup.go b/src/sync/waitgroup.go
index efc63be099..0bd618a241 100644
--- a/src/sync/waitgroup.go
+++ b/src/sync/waitgroup.go
@@ -83,13 +83,17 @@ func (wg *WaitGroup) Add(delta int) {
race.Disable()
defer race.Enable()
}
+ bubbled := false
if synctest.IsInBubble() {
// If Add is called from within a bubble, then all Add calls must be made
// from the same bubble.
- if !synctest.Associate(wg) {
+ switch synctest.Associate(wg) {
+ case synctest.Unbubbled:
+ case synctest.OtherBubble:
// wg is already associated with a different bubble.
fatal("sync: WaitGroup.Add called from multiple synctest bubbles")
- } else {
+ case synctest.CurrentBubble:
+ bubbled = true
state := wg.state.Or(waitGroupBubbleFlag)
if state != 0 && state&waitGroupBubbleFlag == 0 {
// Add has been called from outside this bubble.
@@ -98,7 +102,7 @@ func (wg *WaitGroup) Add(delta int) {
}
}
state := wg.state.Add(uint64(delta) << 32)
- if state&waitGroupBubbleFlag != 0 && !synctest.IsInBubble() {
+ if state&waitGroupBubbleFlag != 0 && !bubbled {
// Add has been called from within a synctest bubble (and we aren't in one).
fatal("sync: WaitGroup.Add called from inside and outside synctest bubble")
}
@@ -116,7 +120,7 @@ func (wg *WaitGroup) Add(delta int) {
if w != 0 && delta > 0 && v == int32(delta) {
panic("sync: WaitGroup misuse: Add called concurrently with Wait")
}
- if v == 0 && state&waitGroupBubbleFlag != 0 {
+ if v == 0 && bubbled {
// Disassociate the WaitGroup from its bubble.
synctest.Disassociate(wg)
if w == 0 {