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

  1. Verify the binary/core's .debug_line section is complete (unit_length bounds the program).
  2. Check how the buffer for this line program unit was sliced — a wrong unit_length leads to premature EOF.
  3. Update Delve; newer versions may report a line-table parse error instead of panicking.
  4. 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

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


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