From: Austin Clements Date: Mon, 25 Apr 2022 16:25:59 +0000 (-0400) Subject: runtime: fix stack-move sensitivity in some tests X-Git-Tag: go1.19beta1~554 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8619d3b2ec5d23d39acb4968ce7938230e0728ad;p=gostls13.git runtime: fix stack-move sensitivity in some tests There are a few tests of the scheduler run queue API that allocate a local []g and test using those G's. However, the run queue API frequently converts between *g and guintptr, which is safe for "real" Gs because they're heap-allocated and hence don't move, but if these tests get a stack movement while holding one of these local *g's as a guintptr, it won't get updated and the test will fail. Updates #48297. Change-Id: Ifd424147ce1a1b53732ff0cf55a81df1a9beeb3b Reviewed-on: https://go-review.googlesource.com/c/go/+/402157 Run-TryBot: Austin Clements TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui --- diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go index 8a81f42ca0..0a00801a11 100644 --- a/src/runtime/export_test.go +++ b/src/runtime/export_test.go @@ -85,6 +85,7 @@ func GCMask(x any) (ret []byte) { func RunSchedLocalQueueTest() { _p_ := new(p) gs := make([]g, len(_p_.runq)) + escape(gs) // Ensure gs doesn't move, since we use guintptrs for i := 0; i < len(_p_.runq); i++ { if g, _ := runqget(_p_); g != nil { throw("runq is not empty initially") @@ -108,6 +109,7 @@ func RunSchedLocalQueueStealTest() { p1 := new(p) p2 := new(p) gs := make([]g, len(p1.runq)) + escape(gs) // Ensure gs doesn't move, since we use guintptrs for i := 0; i < len(p1.runq); i++ { for j := 0; j < i; j++ { gs[j].sig = 0 @@ -155,6 +157,7 @@ func RunSchedLocalQueueEmptyTest(iters int) { done := make(chan bool, 1) p := new(p) gs := make([]g, 2) + escape(gs) // Ensure gs doesn't move, since we use guintptrs ready := new(uint32) for i := 0; i < iters; i++ { *ready = 0 @@ -1257,7 +1260,7 @@ func NewGCController(gcPercent int) *GCController { // do 64-bit atomics on it, and if it gets stack-allocated // on a 32-bit architecture, it may get allocated unaligned // space. - g := escape(new(GCController)).(*GCController) + g := escape(new(GCController)) g.gcControllerState.test = true // Mark it as a test copy. g.init(int32(gcPercent)) return g @@ -1318,7 +1321,8 @@ func (c *GCController) EndCycle(bytesMarked uint64, assistTime, elapsed int64, g var escapeSink any //go:noinline -func escape(x any) any { +//go:norace +func escape[T any](x T) T { escapeSink = x escapeSink = nil return x