]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: set stackguard1 on extra M g0
authorMichael Pratt <mpratt@google.com>
Fri, 8 Sep 2023 18:54:29 +0000 (14:54 -0400)
committerMichael Pratt <mpratt@google.com>
Mon, 11 Sep 2023 14:46:55 +0000 (14:46 +0000)
Standard Ms set g0.stackguard1 to the same value as stackguard0 in
mstart0. For consistency, extra Ms should do the same for their g0. Do
this in needm -> callbackUpdateSystemStack.

Background: getg().stackguard1 is used as the stack guard for the stack
growth prolouge in functions marked //go:systemstack [1]. User Gs set
stackguard1 to ^uintptr(0) so that the check always fail, calling
morestackc, which throws to report a //go:systemstack function call on a
user stack.

g0 setting stackguard1 is unnecessary for this functionality. 0 would be
sufficient, as g0 is always allowed to call //go:systemstack functions.
However, since we have the check anyway, setting stackguard1 to the
actual stack bound is useful to detect actual stack overflows on g0
(though morestackc doesn't detect this case and would report a
misleading message about user stacks).

[1] cmd/internal/obj calls //go:systemstack functions AttrCFunc. This is
a holdover from when the runtime contained actual C functions. But since
CL 2275, it has simply meant "pretend this is a C function, which would
thus need to use the system stack". Hence the name morestackc. At this
point, this terminology is pretty far removed from reality and should
probably be updated to something more intuitive.

Change-Id: I8d0e5628ce31ac6a189a7d7a4124be85aef89862
Reviewed-on: https://go-review.googlesource.com/c/go/+/527056
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/runtime/cgocall.go
src/runtime/runtime2.go

index debd8cf5e8a59877fccafbcd60ae8035a6f4001b..e4da34b31d5c309b6e32c7ea4a006ac00dc4fc05 100644 (file)
@@ -233,6 +233,7 @@ func callbackUpdateSystemStack(mp *m, sp uintptr, signal bool) {
                g0.stack.hi = sp + 1024
                g0.stack.lo = sp - 32*1024
                g0.stackguard0 = g0.stack.lo + stackGuard
+               g0.stackguard1 = g0.stackguard0
 
                print("M ", mp.id, " procid ", mp.procid, " runtime: cgocallback with sp=", hex(sp), " out of bounds [", hex(lo), ", ", hex(hi), "]")
                print("\n")
@@ -271,6 +272,7 @@ func callbackUpdateSystemStack(mp *m, sp uintptr, signal bool) {
                }
        }
        g0.stackguard0 = g0.stack.lo + stackGuard
+       g0.stackguard1 = g0.stackguard0
 }
 
 // Call from C back to Go. fn must point to an ABIInternal Go entry-point.
index 8809b5d569c787924f06e75190e61b3506caee2a..34f66d4ada0cf6ed050374d12a96a34fc735beb2 100644 (file)
@@ -423,7 +423,7 @@ type g struct {
        // stack describes the actual stack memory: [stack.lo, stack.hi).
        // stackguard0 is the stack pointer compared in the Go stack growth prologue.
        // It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
-       // stackguard1 is the stack pointer compared in the C stack growth prologue.
+       // stackguard1 is the stack pointer compared in the //go:systemstack stack growth prologue.
        // It is stack.lo+StackGuard on g0 and gsignal stacks.
        // It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
        stack       stack   // offset known to runtime/cgo