Skip to content

Commit 8619d3b

Browse files
committed
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 <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 12763d1 commit 8619d3b

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

src/runtime/export_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ func GCMask(x any) (ret []byte) {
8585
func RunSchedLocalQueueTest() {
8686
_p_ := new(p)
8787
gs := make([]g, len(_p_.runq))
88+
escape(gs) // Ensure gs doesn't move, since we use guintptrs
8889
for i := 0; i < len(_p_.runq); i++ {
8990
if g, _ := runqget(_p_); g != nil {
9091
throw("runq is not empty initially")
@@ -108,6 +109,7 @@ func RunSchedLocalQueueStealTest() {
108109
p1 := new(p)
109110
p2 := new(p)
110111
gs := make([]g, len(p1.runq))
112+
escape(gs) // Ensure gs doesn't move, since we use guintptrs
111113
for i := 0; i < len(p1.runq); i++ {
112114
for j := 0; j < i; j++ {
113115
gs[j].sig = 0
@@ -155,6 +157,7 @@ func RunSchedLocalQueueEmptyTest(iters int) {
155157
done := make(chan bool, 1)
156158
p := new(p)
157159
gs := make([]g, 2)
160+
escape(gs) // Ensure gs doesn't move, since we use guintptrs
158161
ready := new(uint32)
159162
for i := 0; i < iters; i++ {
160163
*ready = 0
@@ -1257,7 +1260,7 @@ func NewGCController(gcPercent int) *GCController {
12571260
// do 64-bit atomics on it, and if it gets stack-allocated
12581261
// on a 32-bit architecture, it may get allocated unaligned
12591262
// space.
1260-
g := escape(new(GCController)).(*GCController)
1263+
g := escape(new(GCController))
12611264
g.gcControllerState.test = true // Mark it as a test copy.
12621265
g.init(int32(gcPercent))
12631266
return g
@@ -1318,7 +1321,8 @@ func (c *GCController) EndCycle(bytesMarked uint64, assistTime, elapsed int64, g
13181321
var escapeSink any
13191322

13201323
//go:noinline
1321-
func escape(x any) any {
1324+
//go:norace
1325+
func escape[T any](x T) T {
13221326
escapeSink = x
13231327
escapeSink = nil
13241328
return x

0 commit comments

Comments
 (0)