{"record":{"id":"542b9c4370cfabc8","repo":"go-delve/delve","slug":"failed-to-extract-call-destination-from-instructio","errorCode":null,"errorMessage":"failed to extract call destination from instruction at PC %#x","messagePattern":"failed to extract call destination from instruction at PC %#x","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/debugger/debugger.go","lineNumber":1509,"sourceCode":"\t\t\t\t\tregs, err := th.Registers()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"registers inside callback returned err\")\n\n\t\t\t\t\t}\n\t\t\t\t\t// Disassemble the instruction at the current PC to get the call destination\n\t\t\t\t\tpc := instr.Loc.PC\n\t\t\t\t\tmaxInstLen := uint64(tgt.BinInfo().Arch.MaxInstructionLength())\n\t\t\t\t\tdisasm, err := proc.Disassemble(t.Memory(), regs, t.Breakpoints(), tgt.BinInfo(), pc, pc+maxInstLen)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"failed to disassemble instruction: %w\", err)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Extract address from the decoded instruction's destination location\n\t\t\t\t\tvar addr uint64\n\t\t\t\t\tif len(disasm) > 0 && disasm[0].DestLoc != nil {\n\t\t\t\t\t\taddr = disasm[0].DestLoc.PC\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"failed to extract call destination from instruction at PC %#x\", pc)\n\t\t\t\t\t}\n\t\t\t\t\tfn := tgt.BinInfo().PCToFunc(addr)\n\t\t\t\t\tif fn == nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"PCToFunc returned nil\")\n\t\t\t\t\t}\n\t\t\t\t\terr = createFunctionTracepoints(d, fn.Name, rootstr, followCalls)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"error creating tracepoint in function %s\", fn.Name)\n\t\t\t\t\t}\n\t\t\t\t\tdynchildren, err := d.traverse(t, fn, sdepth+1, followCalls, rootstr)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"error calling traverse on dynamic children\")\n\t\t\t\t\t}\n\t\t\t\t\tfor _, child := range dynchildren {\n\t\t\t\t\t\terr := createFunctionTracepoints(d, child, rootstr, followCalls)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn false, fmt.Errorf(\"error creating tracepoint in function %s\", child)\n\t\t\t\t\t\t}","sourceCodeStart":1491,"sourceCodeEnd":1527,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/debugger/debugger.go#L1491-L1527","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check that regs from th.Registers() correspond to the thread that actually hit the breakpoint (PC should equal the breakpoint PC).","Retry the trace; transient state (e.g. breakpoint just being stepped over) can produce empty disassembly.","Verify the binary was not rebuilt/reloaded after breakpoints were set (recompile invalidates cached instruction bytes).","Report the exact PC and GOARCH to the Delve project if consistently reproducible."],"exampleFix":"// before\nif len(disasm) > 0 && disasm[0].DestLoc != nil {\n\taddr = disasm[0].DestLoc.PC\n} else {\n\treturn false, fmt.Errorf(\"failed to extract call destination from instruction at PC %#x\", pc)\n}\n// after (treat missing destination as benign skip, not fatal, when depth budget is tight)\nif len(disasm) == 0 || disasm[0].DestLoc == nil {\n\tlog.Debugf(\"no resolvable destination for call at %#x; skipping\", pc)\n\treturn false, nil\n}\naddr = disasm[0].DestLoc.PC","handlingStrategy":"fallback","validationCode":"// sanity-check that indirect call sites in your hot functions are resolvable\n// by disassembling the function statically before tracing:\nout, err := exec.Command(\"go\", \"tool\", \"objdump\", \"-s\", \"myfunc\", os.Args[1]).Output()\nif err != nil {\n\tlog.Fatal(\"cannot disassemble target binary; trace will fail on indirect calls\")\n}","typeGuard":null,"tryCatchPattern":"if err := runTrace(); err != nil {\n\tif strings.Contains(err.Error(), \"failed to extract call destination\") {\n\t\tlog.Println(\"indirect call could not be resolved; retrying without dynamic breakpoints\")\n\t\t_ = runTrace(TraceOpts{FollowCalls: 0})\n\t\treturn\n\t}\n\treturn err\n}","preventionTips":["Avoid rebuilding the binary after starting a trace session (stale instruction bytes).","Pin trace sessions to binaries built with a supported Go toolchain.","Report persistent unresolved-call PCs with GOARCH details upstream.","Prefer tracing direct-call-heavy functions when using follow-calls."],"tags":["debugger","disassembly","ebpf","indirect-call"],"backgroundTag":"call-destination-unresolved","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}