1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build unix && !android && !openbsd
6
7package main
8
9/*
10void callStackSwitchCallbackFromThread(void);
11*/
12import "C"
13
14import (
15	"fmt"
16	"runtime/debug"
17)
18
19func init() {
20	register("StackSwitchCallback", StackSwitchCallback)
21}
22
23//export stackSwitchCallback
24func stackSwitchCallback() {
25	// We want to trigger a bounds check on the g0 stack. To do this, we
26	// need to call a splittable function through systemstack().
27	// SetGCPercent contains such a systemstack call.
28	gogc := debug.SetGCPercent(100)
29	debug.SetGCPercent(gogc)
30}
31
32// Regression test for https://go.dev/issue/62440. It should be possible for C
33// threads to call into Go from different stacks without crashing due to g0
34// stack bounds checks.
35//
36// N.B. This is only OK for threads created in C. Threads with Go frames up the
37// stack must not change the stack out from under us.
38func StackSwitchCallback() {
39	C.callStackSwitchCallbackFromThread()
40
41	fmt.Printf("OK\n")
42}
43