{"record":{"id":"e7e1d2aee1c4d56a","repo":"go-delve/delve","slug":"failed-to-disassemble-instruction-w","errorCode":null,"errorMessage":"failed to disassemble instruction: %w","messagePattern":"failed to disassemble instruction: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/debugger/debugger.go","lineNumber":1501,"sourceCode":"\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsdepth := rootindex + 1\n\n\t\t\t\t\tif sdepth+1 > followCalls {\n\t\t\t\t\t\treturn false, nil\n\t\t\t\t\t}\n\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)","sourceCodeStart":1483,"sourceCodeEnd":1519,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/debugger/debugger.go#L1483-L1519","documentation":"Delve's dynamic-tracepoint callback (in traverse, used by eBPF follow-calls tracing) hits an indirect call at runtime and re-disassembles the single instruction at its PC to resolve the call destination. This error wraps any failure from proc.Disassemble for that one-instruction range. Because the static pass already disassembled the whole function successfully, failure here usually means memory at the PC is unreadable at callback time (process exited, memory unmapped) or the architecture backend could not decode the bytes.","triggerScenarios":"Returned from the dynCallback breakpoint callback when proc.Disassemble(t.Memory(), regs, t.Breakpoints(), tgt.BinInfo(), pc, pc+maxInstLen) fails while resolving an indirect call (instr.IsCall() && instr.DestLoc == nil) during 'dlv trace --follow-calls' with the eBPF backend.","commonSituations":"Target process exited or its memory changed between setting the dynamic breakpoint and hitting it; attaching to a stripped/partially-mapped binary; architectures with limited disassembler support; tracing through cgo or JIT-ed code regions where PC points at non-Go memory.","solutions":["Re-run trace to rule out a transient failure caused by the target dying mid-trace (check with 'dlv attach' or process status first).","Verify the traced binary is a complete, unstripped Go build (go build without -ldflags=\"-s -w\").","Confirm the eBPF backend supports your GOARCH; try tracing a smaller/caller function to isolate the failing call site.","Reduce --follow-calls depth so fewer indirect call sites get dynamic breakpoints.","If reproducible, file an issue with the PC value and the wrapped inner error from %w."],"exampleFix":"// before (error surfaced with no context of which function)\nreturn false, fmt.Errorf(\"failed to disassemble instruction: %w\", err)\n// after (add PC + function context to the wrap)\nreturn false, fmt.Errorf(\"failed to disassemble instruction at PC %#x in %s: %w\", pc, f.Name, err)","handlingStrategy":"try-catch","validationCode":"// before invoking dlv trace with eBPF follow-calls\ndlvcmd := exec.Command(\"dlv\", \"trace\", \"--backend=ebpf\", \"--follow-calls=2\", \"--\", \"./mybin\")\nif err := dlvcmd.Run(); err != nil {\n\tif strings.Contains(fmt.Sprint(err), \"failed to disassemble instruction\") {\n\t\tlog.Println(\"binary may be stripped or unsupported arch; rebuild unstripped for\", runtime.GOARCH)\n\t}\n}","typeGuard":"func isDisasmFailure(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"failed to disassemble instruction\")\n}","tryCatchPattern":"err := dlvCmd.Run()\nvar handled bool\nif err != nil {\n\tswitch {\n\tcase isDisasmFailure(err):\n\t\t// fall back to non-follow-calls tracing\n\t\thandled = retryWithoutFollowCalls()\n\tcase isTransient(err):\n\t\thandled = retryWithBackoff(3, time.Second, dlvCmd.Run)\n\t}\n\tif !handled {\n\t\tlog.Fatalf(\"trace failed: %v\", err)\n\t}\n}","preventionTips":["Always trace unstripped binaries (avoid -ldflags \"-s -w\").","Verify GOARCH is one Delve's eBPF backend supports before tracing.","Keep the target process alive while tracepoints are installed.","Test follow-calls tracing on a small function first to isolate call sites that fail."],"tags":["debugger","disassembly","ebpf","follow-calls"],"backgroundTag":"disassemble-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}