aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/debugcall.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/debugcall.go')
-rw-r--r--src/runtime/debugcall.go32
1 files changed, 22 insertions, 10 deletions
diff --git a/src/runtime/debugcall.go b/src/runtime/debugcall.go
index 2fe0b1d12f..faddf59eed 100644
--- a/src/runtime/debugcall.go
+++ b/src/runtime/debugcall.go
@@ -16,7 +16,7 @@ const (
debugCallUnsafePoint = "call not at safe point"
)
-func debugCallV1()
+func debugCallV2()
func debugCallPanicked(val interface{})
// debugCallCheck checks whether it is safe to inject a debugger
@@ -96,7 +96,7 @@ func debugCallCheck(pc uintptr) string {
// function at PC dispatch.
//
// This must be deeply nosplit because there are untyped values on the
-// stack from debugCallV1.
+// stack from debugCallV2.
//
//go:nosplit
func debugCallWrap(dispatch uintptr) {
@@ -108,14 +108,16 @@ func debugCallWrap(dispatch uintptr) {
// Create a new goroutine to execute the call on. Run this on
// the system stack to avoid growing our stack.
systemstack(func() {
- var args struct {
- dispatch uintptr
- callingG *g
- }
- args.dispatch = dispatch
- args.callingG = gp
+ // TODO(mknyszek): It would be nice to wrap these arguments in an allocated
+ // closure and start the goroutine with that closure, but the compiler disallows
+ // implicit closure allocation in the runtime.
fn := debugCallWrap1
- newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), unsafe.Pointer(&args), int32(unsafe.Sizeof(args)), gp, callerpc)
+ newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), nil, 0, gp, callerpc)
+ args := &debugCallWrapArgs{
+ dispatch: dispatch,
+ callingG: gp,
+ }
+ newg.param = unsafe.Pointer(args)
// If the current G is locked, then transfer that
// locked-ness to the new goroutine.
@@ -185,9 +187,19 @@ func debugCallWrap(dispatch uintptr) {
gp.asyncSafePoint = false
}
+type debugCallWrapArgs struct {
+ dispatch uintptr
+ callingG *g
+}
+
// debugCallWrap1 is the continuation of debugCallWrap on the callee
// goroutine.
-func debugCallWrap1(dispatch uintptr, callingG *g) {
+func debugCallWrap1() {
+ gp := getg()
+ args := (*debugCallWrapArgs)(gp.param)
+ dispatch, callingG := args.dispatch, args.callingG
+ gp.param = nil
+
// Dispatch call and trap panics.
debugCallWrap2(dispatch)