go-delve/delve · error
%v
Error message
%v
What it means
When the Go runtime rejects an injected function call (e.g. goroutine is in a non-callable state, stack too small, unsafepoint issues), it leaves an error string on the stack. Delve reads it with readStackVariable and rethrows it verbatim via fmt.Errorf("%v", ...). This is the propagated runtime reason for the failed call injection.
Source
Thrown at pkg/proc/fncall.go:853
}
switch regval {
case debugCallRegPrecheckFailed: // 8
stack.callInjectionContinue = true
archoff := uint64(0)
if bi.Arch.Name == "arm64" || bi.Arch.Name == "loong64" {
archoff = 8
} else if bi.Arch.Name == "ppc64le" {
archoff = 40
}
// get error from top of the stack and return it to user
errvar, err := readStackVariable(p, thread, regs, archoff, "string", LoadFullValue())
if err != nil {
fncall.err = fmt.Errorf("could not get precheck error reason: %v", err)
break
}
errvar.Name = "err"
fncall.err = fmt.Errorf("%v", constant.StringVal(errvar.Value))
case debugCallRegCompleteCall: // 0
p.fncallForG[callScope.g.ID].startThreadID = 0
case debugCallRegRestoreRegisters: // 16
// runtime requests that we restore the registers (all except pc and sp),
// this is also the last step of the function call protocol.
pc, sp := regs.PC(), regs.SP()
if err := thread.RestoreRegisters(fncall.savedRegs); err != nil {
fncall.err = fmt.Errorf("could not restore registers: %v", err)
}
if err := setPC(thread, pc); err != nil {
fncall.err = fmt.Errorf("could not restore PC: %v", err)
}
if err := setSP(thread, sp); err != nil {
fncall.err = fmt.Errorf("could not restore SP: %v", err)
}
fncallLog("stepping thread %d", thread.ThreadID())View on GitHub (pinned to a23773e6c3)
Solutions
- Read the wrapped message: it names the actual runtime reason (e.g. 'go exit status', 'not at a safe point')
- Ensure the goroutine is stopped at a normal Go frame before calling
- Avoid injecting calls from runtime or signal-handler frames
- Retry after stepping the program to a safe location
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the goroutine is in a callable state before 'call': // check state.CurrentThread.ReturnValues / frame is not in runtime or signal code // e.g. via disassemble/state: strings.Contains(frame.Fn.Name, "runtime.") == false
Try / catch
err := dbg.CallFunction(scope, fn, args)
if err != nil {
// The wrapped text IS the runtime's reason: parse and surface it
log.Printf("call rejected by runtime: %v", err)
}
Prevention
- Only inject calls from normal user-code frames
- Avoid calling functions from signal handlers or system goroutines
- Step out of runtime frames before calling
- Read the wrapped message — it names the actual runtime objection
When it happens
Trigger: funcCallStep reads the debug-call error string from the stack during the precondition-check phase of debugCallV2 and the string is non-empty — the runtime refused the call.
Common situations: Calling a function while the goroutine is running or in a runtime critical section; calling functions from within runtime/internal frames; calling a function that grows the stack beyond limits; using 'call' inside a breakpoint in a signal handler or system goroutine.
Related errors
- could not find goroutine array
- map index out of bounds
- internal debugger error: eval program finished without error
- internal debugger error: could not undo injected call during
- unsupported pointer size %d
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/7f272fb02de820f1.
Report an issue: GitHub.