aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/synctest.go
AgeCommit message (Collapse)Author
2025-06-10testing/synctest, runtime: avoid panic when using linker-alloc WG from bubbleDamien Neil
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>
2025-06-09runtime: return a different bubble deadlock error when main goroutine is doneDamien Neil
The synctest.Test function waits for all goroutines in a bubble to exit before returning. If there is ever a point when all goroutines in a bubble are durably blocked, it panics and reports a deadlock. Panic with a different message depending on whether the bubble's main goroutine has returned or not. The main goroutine returning stops the bubble clock, so knowing whether it is running or not is useful debugging information. The new panic messages are: deadlock: all goroutines in bubble are blocked deadlock: main bubble goroutine has exited but blocked goroutines remain Change-Id: I94a69e79121c272d9c86f412c1c9c7de57ef27ef Reviewed-on: https://go-review.googlesource.com/c/go/+/679375 Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-06-04runtime: make bubbled timers more consistent with unbubbledDamien Neil
This CL makes two changes to reduce the predictability with which bubbled timers fire. When asynctimerchan=0 (the default), regular timers with an associated channel are only added to a timer heap when some channel operation is blocked on that channel. This allows us to garbage collect unreferenced, unstopped timers. Timers in a synctest bubble, in contrast, are always added to the bubble's timer heap. This CL changes bubbled timers with a channel to be handled the same as unbubbled ones, adding them to the bubble's timer heap only when some channel operation is blocked on the timer's channel. This permits unstopped bubbled timers to be garbage collected, but more importantly it makes all timers past their deadline behave identically, regardless of whether they are in a bubble. This CL also changes timer scheduling to execute bubbled timers immediately when possible rather than adding them to a heap. Timers in a bubble's heap are executed when the bubble is idle. Executing timers immediately avoids creating a predictable order of execution. For #73850 Fixes #73934 Change-Id: If82e441546408f780f6af6fb7f6e416d3160295d Reviewed-on: https://go-review.googlesource.com/c/go/+/678075 Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-29runtime, internal/synctest, sync: associate WaitGroups with bubblesDamien Neil
Add support to internal/synctest for managing associations between arbitrary pointers and synctest bubbles. (Implemented internally to the runtime package by attaching a special to the pointer.) Associate WaitGroups with bubbles. Since WaitGroups don't have a constructor, perform the association when Add is called. All Add calls must be made from within the same bubble, or outside any bubble. When a bubbled goroutine calls WaitGroup.Wait, the wait is durably blocking iff the WaitGroup is associated with the current bubble. Change-Id: I77e2701e734ac2fa2b32b28d5b0c853b7b2825c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/676656 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com>
2025-05-07runtime: use "bubble" terminology for synctestDamien Neil
We've settled on calling the group of goroutines started by synctest.Run a "bubble". At the time the runtime implementation was written, I was still calling this a "group". Update the code to match the current terminology. Change-Id: I31b757f31d804b5d5f9564c182627030a9532f4a Reviewed-on: https://go-review.googlesource.com/c/go/+/670135 Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-07runtime, testing/synctest: stop advancing time when main goroutine exitsDamien Neil
Once the goroutine started by synctest.Run exits, stop advancing the fake clock in its bubble. This avoids confusing situations where a bubble remains alive indefinitely while a background goroutine reads from a time.Ticker or otherwise advances the clock. For #67434 Change-Id: Id608ffe3c7d7b07747b56a21f365787fb9a057d7 Reviewed-on: https://go-review.googlesource.com/c/go/+/662155 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com>
2025-05-07runtime: print stack traces for bubbled goroutines on synctest deadlockDamien Neil
When synctest.Run panics due to every goroutine in the bubble being blocked, print a stack trace for every goroutine in the bubble. For #67434 Change-Id: Ie751c2ee6fa136930b18f4bee0277ff30da46905 Reviewed-on: https://go-review.googlesource.com/c/go/+/645719 Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-03-21runtime: fix interactions between synctest, race detector, and timersDamien Neil
When an AfterFunc executes in a synctest bubble, there is a series of happens-before relationships: 1. The AfterFunc is created. 2. The AfterFunc goroutine executes. 3. The AfterFunc goroutine returns. 4. A subsequent synctest.Wait call returns. We were failing to correctly establish the happens-before relationship between the AfterFunc goroutine and the AfterFunc itself being created. When an AfterFunc executes, the G running the timer temporarily switches to the timer heap's racectx. It then calls time.goFunc, which starts a new goroutine to execute the timer. time.goFunc relies on the new goroutine inheriting the racectx of the G running the timer. Normal, non-synctest timers, execute with m.curg == nil, which causes new goroutines to inherit the g0 racectx. We were running synctest timers with m.curg set (to the G executing synctest.Run), so the new AfterFunc goroutine was created using m.curg's racectx. This resulted in us not properly establishing the happens-before relationship between AfterFunc being called and the AfterFunc goroutine starting. Fix this by setting m.curg to nil while executing timers. As one additional fix, when waking a blocked bubble, wake the root goroutine rather than a goroutine blocked in Wait if there is a timer that can fire. Fixes #72750 Change-Id: I2b2d6b0f17f64649409adc93c2603f720494af89 Reviewed-on: https://go-review.googlesource.com/c/go/+/658595 Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2025-02-10runtime: establish happens-before between goroutine and bubble exitDamien Neil
synctest.Run waits for all bubbled goroutines to exit before returning. Establish a happens-before relationship between the bubbled goroutines exiting and Run returning. For #67434 Change-Id: Ibda7ec2075ae50838c0851e60dc5b3c6f3ca70fb Reviewed-on: https://go-review.googlesource.com/c/go/+/647755 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2024-12-03runtime: avoid defer on system stack in synctestidle_cDamien Neil
Fixes #70661 Change-Id: I58a465cfb1cd16709ffbb072eca0997569540074 Reviewed-on: https://go-review.googlesource.com/c/go/+/633281 Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-11-22runtime, internal/synctest, syscall/js: keep bubble membership in syscallsDamien Neil
Propagate synctest bubble membership through syscall/js.Func functions. Avoids panics from cross-bubble channel operations in js syscalls. Fixes #70512 Change-Id: Idbd9f95da8bc4f055a635dfac041359f848dad1a Reviewed-on: https://go-review.googlesource.com/c/go/+/631055 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com>
2024-11-20runtime: avoid deadlock in synctest changegstatus when copying stacksDamien Neil
For #67434 Fixes #70452 Change-Id: Ie655a9e55837aa68b6bfb0bb69b6c8caaf3bbea5 Reviewed-on: https://go-review.googlesource.com/c/go/+/629856 Reviewed-by: Russ Cox <rsc@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2024-11-19internal/synctest: new package for testing concurrent codeDamien Neil
Add an internal (for now) implementation of testing/synctest. The synctest.Run function executes a tree of goroutines in an isolated environment using a fake clock. The synctest.Wait function allows a test to wait for all other goroutines within the test to reach a blocking point. For #67434 For #69687 Change-Id: Icb39e54c54cece96517e58ef9cfb18bf68506cfc Reviewed-on: https://go-review.googlesource.com/c/go/+/591997 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>