go-delve/delve · error
start address(%x) should be less than end address(%x)
Error message
start address(%x) should be less than end address(%x)
What it means
proc.Disassemble disassembles machine code in the address range [startAddr, endAddr) of the target's memory. It rejects calls where startAddr > endAddr with this error, because a reversed range is meaningless and downstream code allocates a buffer of size startAddr-endAddr. Equal addresses are allowed and yield an empty instruction list.
Source
Thrown at pkg/proc/disasm.go:125
func checkPrologue(s []AsmInstruction, prologuePattern opcodeSeq) bool {
line := s[0].Loc.Line
for i, op := range prologuePattern {
if !s[i].Inst.OpcodeEquals(op) || s[i].Loc.Line != line {
return false
}
}
return true
}
// Disassemble disassembles target memory between startAddr and endAddr, marking
// the current instruction being executed in goroutine g.
// If currentGoroutine is set and thread is stopped at a CALL instruction Disassemble
// will evaluate the argument of the CALL instruction using the thread's registers.
// Be aware that the Bytes field of each returned instruction is a slice of a larger array of size startAddr - endAddr.
func Disassemble(mem MemoryReadWriter, regs Registers, breakpoints *BreakpointMap, bi *BinaryInfo, startAddr, endAddr uint64) ([]AsmInstruction, error) {
if startAddr > endAddr {
return nil, fmt.Errorf("start address(%x) should be less than end address(%x)", startAddr, endAddr)
}
return disassemble(mem, regs, breakpoints, bi, startAddr, endAddr, false)
}
func disassemble(memrw MemoryReadWriter, regs Registers, breakpoints *BreakpointMap, bi *BinaryInfo, startAddr, endAddr uint64, singleInstr bool) ([]AsmInstruction, error) {
var dregs *op.DwarfRegisters
if regs != nil {
dregs = bi.Arch.RegistersToDwarfRegisters(0, regs)
}
mem := make([]byte, int(endAddr-startAddr))
_, err := memrw.ReadMemory(mem, startAddr)
if err != nil {
return nil, err
}
r := make([]AsmInstruction, 0, len(mem)/bi.Arch.MaxInstructionLength())
pc := startAddrView on GitHub (pinned to a23773e6c3)
Solutions
- Swap the arguments so startAddr is the lower address (e.g. min/max the two values).
- Check where the bounds are computed (e.g. fn.Entry/fn.End from the symbol table) and fix the reversal or underflow.
- For RPC/DAP clients, verify the Start and End fields sent in the request are ordered ascending.
- Add a guard before calling: only invoke when endAddr > startAddr, else return an empty result.
Example fix
// before insns, err := proc.Disassemble(mem, regs, bp, bi, fn.End, fn.Entry) // swapped // after insns, err := proc.Disassemble(mem, regs, bp, bi, fn.Entry, fn.End)
Defensive patterns
Strategy: validation
Validate before calling
func safeDisassemble(mem proc.MemoryReadWriter, regs proc.Registers, bp *proc.BreakpointMap, bi *proc.BinaryInfo, start, end uint64) ([]proc.AsmInstruction, error) {
if start > end {
start, end = end, start
}
return proc.Disassemble(mem, regs, bp, bi, start, end)
} Type guard
func validRange(start, end uint64) bool {
return start <= end
} Try / catch
insns, err := proc.Disassemble(mem, regs, bp, bi, startAddr, endAddr)
if err != nil {
if strings.Contains(err.Error(), "should be less than end address") {
startAddr, endAddr = endAddr, startAddr
insns, err = proc.Disassemble(mem, regs, bp, bi, startAddr, endAddr)
}
if err != nil { return nil, err }
} Prevention
- Always derive ranges as (fn.Entry, fn.End) from the symbol table, not ad-hoc math.
- Watch for unsigned arithmetic underflow when computing endAddr = x - n.
- In RPC/DAP clients, assert Start < End before sending the request.
- Unit-test range computation helpers with reversed and zero-length cases.
When it happens
Trigger: Calling proc.Disassemble (or its public callers findRetPC, setStepIntoNewProcBreakpoint, skipAutogeneratedWrappersIn, and service-level StepInto/Disassemble RPC/DAP requests) with swapped or computed bounds such that startAddr > endAddr.
Common situations: A client computing a function's range from a symbol table with reversed hi/lo bounds; endAddr computed as funcEnd - n with unsigned underflow; an RPC client sending incorrectly ordered Start/End arguments.
Related errors
- clear-checkpoint argument must be a checkpoint ID
- too many arguments
- wrong number of arguments to "config"
- could not find CALL instruction for address %#x in %s
- wrong argument: %q is not a number
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/b4e55bca3c409693.
Report an issue: GitHub.