go-delve/delve · error
panic(err)
Error message
panic(err)
What it means
The DWARF line-table state machine's `setaddress` (DW_LNS_set_address extended opcode) handler panics with the raw io error when dwarf.ReadUintRaw cannot read ptrSize bytes from the line program buffer. This indicates the .debug_line section is truncated or the state machine is reading past the end of the program. The library assumes well-formed line data and treats EOF as fatal.
Source
Thrown at pkg/dwarf/line/state_machine.go:526
sm.address += uint64((255-sm.dbl.Prologue.OpcodeBase)/sm.dbl.Prologue.LineRange) * uint64(sm.dbl.Prologue.MinInstrLength)
}
func fixedadvancepc(sm *StateMachine, buf *bytes.Buffer) {
var operand uint16
binary.Read(buf, binary.LittleEndian, &operand)
sm.address += uint64(operand)
}
func endsequence(sm *StateMachine, buf *bytes.Buffer) {
sm.endSeq = true
sm.valid = sm.dbl.endSeqIsValid
}
func setaddress(sm *StateMachine, buf *bytes.Buffer) {
addr, err := dwarf.ReadUintRaw(buf, binary.LittleEndian, sm.ptrSize)
if err != nil {
panic(err)
}
sm.address = addr + sm.dbl.staticBase
}
func setdiscriminator(sm *StateMachine, buf *bytes.Buffer) {
_, _ = leb128.DecodeUnsigned(buf)
}
func definefile(sm *StateMachine, buf *bytes.Buffer) {
if entry := readFileEntry(sm.dbl, sm.buf, false); entry != nil {
sm.definedFiles = append(sm.definedFiles, entry)
}
}
func prologueend(sm *StateMachine, buf *bytes.Buffer) {
sm.prologueEnd = true
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Verify the binary/core's .debug_line section is complete (unit_length bounds the program).
- Check how the buffer for this line program unit was sliced — a wrong unit_length leads to premature EOF.
- Update Delve; newer versions may report a line-table parse error instead of panicking.
- Recover() around line-table parsing when handling untrusted or third-party binaries.
Example fix
// before
addr, err := dwarf.ReadUintRaw(buf, binary.LittleEndian, sm.ptrSize)
if err != nil {
panic(err)
}
// after
addr, err := dwarf.ReadUintRaw(buf, binary.LittleEndian, sm.ptrSize)
if err != nil {
return nil, fmt.Errorf("truncated .debug_line: set_address: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: ensure the line program buffer is at least unit_length bytes
if uint64(len(lineProg)) < unitLength {
return errors.New("truncated .debug_line program")
} Try / catch
// Go
go func() {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("line-table parse failed: %v", r)
}
}()
sm.Run() // state machine over line program
}() Prevention
- Verify .debug_line unit_length bounds before running the state machine
- Avoid slicing line-program buffers with hand-computed lengths
- Use intact binaries/cores (re-dump corrupted cores)
- Recover() when parsing third-party or fuzzed binaries
When it happens
Trigger: Processing a DW_LNS_set_address opcode whose following address bytes extend beyond the buffer end — truncated .debug_line section, incorrect prologue_length/unit_length handling, or corrupted line program data.
Common situations: Stripped or damaged binaries and core dumps; toolchain-produced line tables with inconsistent unit lengths; manual slicing of the line program buffer with wrong boundaries.
Related errors
- Could not parse ULEB128 value
- Could not parse SLEB128 value
- Could not read from instruction buffer
- Could not unread byte
- Could not read byte
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/a8bfd8fd6f6b0dd0.
Report an issue: GitHub.