go-delve/delve · error

failed to extract call destination from instruction at PC %#

Error message

failed to extract call destination from instruction at PC %#x

What it means

After successfully disassembling the instruction at the dynamic call site, Delve expects exactly one instruction whose DestLoc carries the runtime call destination PC. This error is thrown when disasm is empty or disasm[0].DestLoc is nil, i.e. the decoded instruction did not yield a resolvable destination. It means the breakpoint PC no longer corresponds to a decodable call instruction at callback time.

Source

Thrown at service/debugger/debugger.go:1509

					regs, err := th.Registers()
					if err != nil {
						return false, fmt.Errorf("registers inside callback returned err")

					}
					// Disassemble the instruction at the current PC to get the call destination
					pc := instr.Loc.PC
					maxInstLen := uint64(tgt.BinInfo().Arch.MaxInstructionLength())
					disasm, err := proc.Disassemble(t.Memory(), regs, t.Breakpoints(), tgt.BinInfo(), pc, pc+maxInstLen)
					if err != nil {
						return false, fmt.Errorf("failed to disassemble instruction: %w", err)
					}

					// Extract address from the decoded instruction's destination location
					var addr uint64
					if len(disasm) > 0 && disasm[0].DestLoc != nil {
						addr = disasm[0].DestLoc.PC
					} else {
						return false, fmt.Errorf("failed to extract call destination from instruction at PC %#x", pc)
					}
					fn := tgt.BinInfo().PCToFunc(addr)
					if fn == nil {
						return false, fmt.Errorf("PCToFunc returned nil")
					}
					err = createFunctionTracepoints(d, fn.Name, rootstr, followCalls)
					if err != nil {
						return false, fmt.Errorf("error creating tracepoint in function %s", fn.Name)
					}
					dynchildren, err := d.traverse(t, fn, sdepth+1, followCalls, rootstr)
					if err != nil {
						return false, fmt.Errorf("error calling traverse on dynamic children")
					}
					for _, child := range dynchildren {
						err := createFunctionTracepoints(d, child, rootstr, followCalls)
						if err != nil {
							return false, fmt.Errorf("error creating tracepoint in function %s", child)
						}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Check that regs from th.Registers() correspond to the thread that actually hit the breakpoint (PC should equal the breakpoint PC).
  2. Retry the trace; transient state (e.g. breakpoint just being stepped over) can produce empty disassembly.
  3. Verify the binary was not rebuilt/reloaded after breakpoints were set (recompile invalidates cached instruction bytes).
  4. Report the exact PC and GOARCH to the Delve project if consistently reproducible.

Example fix

// before
if len(disasm) > 0 && disasm[0].DestLoc != nil {
	addr = disasm[0].DestLoc.PC
} else {
	return false, fmt.Errorf("failed to extract call destination from instruction at PC %#x", pc)
}
// after (treat missing destination as benign skip, not fatal, when depth budget is tight)
if len(disasm) == 0 || disasm[0].DestLoc == nil {
	log.Debugf("no resolvable destination for call at %#x; skipping", pc)
	return false, nil
}
addr = disasm[0].DestLoc.PC
Defensive patterns

Strategy: fallback

Validate before calling

// sanity-check that indirect call sites in your hot functions are resolvable
// by disassembling the function statically before tracing:
out, err := exec.Command("go", "tool", "objdump", "-s", "myfunc", os.Args[1]).Output()
if err != nil {
	log.Fatal("cannot disassemble target binary; trace will fail on indirect calls")
}

Try / catch

if err := runTrace(); err != nil {
	if strings.Contains(err.Error(), "failed to extract call destination") {
		log.Println("indirect call could not be resolved; retrying without dynamic breakpoints")
		_ = runTrace(TraceOpts{FollowCalls: 0})
		return
	}
	return err
}

Prevention

When it happens

Trigger: dynCallback found len(disasm) == 0 or disasm[0].DestLoc == nil after proc.Disassemble over [pc, pc+maxInstructionLength) for an indirect call during follow-calls eBPF tracing.

Common situations: Register state stale so an indirect call through a register cannot be resolved; the instruction at pc changed (self-modifying/overwritten text); disassembler returned zero instructions for the range; address-size confusion on unusual architectures.

Related errors


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