go-delve/delve · error

could not step out of %s: %v

Error message

could not step out of %s: %v

What it means

Delve steps the thread out of runtime.debugCallV2 to leave the debug-call machinery cleanly. This error wraps any failure from stepInstructionOut, meaning the thread could not be single-stepped out of the debug-call stub.

Source

Thrown at pkg/proc/fncall.go:873

	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())
		if err := stepInstructionOut(callScope.callCtx.grp, p, thread, fncall.debugCallName, fncall.debugCallName); err != nil {
			fncall.err = fmt.Errorf("could not step out of %s: %v", fncall.debugCallName, err)
		}
		if bi.Arch.Name == "amd64" {
			// The tail of debugCallV2 corrupts the state of RFLAGS, we must restore
			// it one extra time after stepping out of it.
			// See https://github.com/go-delve/delve/issues/2985 and
			// TestCallInjectionFlagCorruption
			rflags := bi.Arch.RegistersToDwarfRegisters(0, fncall.savedRegs).Uint64Val(regnum.AMD64_Rflags)
			err := thread.SetReg(regnum.AMD64_Rflags, op.DwarfRegisterFromUint64(rflags))
			if err != nil {
				fncall.err = fmt.Errorf("could not restore RFLAGS register: %v", err)
			}
		}
		return true

	case debugCallRegReadReturn: // 1
		// read return arguments from stack
		stack.callInjectionContinue = true
		if fncall.panicvar != nil || fncall.err != nil {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Clear other breakpoints on the debug-call frames or retry the call
  2. Ensure the Go version of the target is recent enough (debugCallV2, Go 1.14+)
  3. Restart the session if the thread is in an unknown state
  4. Upgrade Delve to pick up fixes for stepping-out regressions
Defensive patterns

Strategy: retry

Validate before calling

// Ensure a recent Go runtime (debugCallV2, Go 1.14+):
// go version -m <binary>  -> confirm go1.14 or newer

Try / catch

err := dbg.CallFunction(scope, fn, args)
if err != nil && strings.Contains(err.Error(), "could not step out") {
	// clear other breakpoints, then retry once
}

Prevention

When it happens

Trigger: funcCallStep calls stepInstructionOut after restoring PC/SP and it returns an error (single-step breakpoint could not be set, thread stopped unexpectedly, step hit an unexpected breakpoint).

Common situations: Other breakpoints or watchpoints firing inside debugCallV2 while stepping out; process dying mid-step; concurrent modifications to breakpoints during the call; very old Go versions lacking debugCallV2 support.

Related errors


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