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

  1. Read the wrapped message: it names the actual runtime reason (e.g. 'go exit status', 'not at a safe point')
  2. Ensure the goroutine is stopped at a normal Go frame before calling
  3. Avoid injecting calls from runtime or signal-handler frames
  4. 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

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


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/7f272fb02de820f1. Report an issue: GitHub.