go-delve/delve · critical
Could not unread byte
Error message
Could not unread byte
What it means
lookupFunc panics when it needs to restore the opcode's argument byte via buf.UnreadByte() and the underlying byte reader refuses the unread. Since a ReadByte just succeeded, an UnreadByte failure means the buffer implementation cannot step back — effectively an invariant violation in the frame decoder's stream handling.
Source
Thrown at pkg/dwarf/frame/table.go:245
switch instruction & high_2_bits {
case DW_CFA_advance_loc:
instruction = DW_CFA_advance_loc
restore = true
case DW_CFA_offset:
instruction = DW_CFA_offset
restore = true
case DW_CFA_restore:
instruction = DW_CFA_restore
restore = true
}
if restore {
// Restore the last byte as it actually contains the argument for the opcode.
err := buf.UnreadByte()
if err != nil {
panic("Could not unread byte")
}
}
return fnlookup[instruction]
}
func advanceloc(frame *FrameContext) {
b, err := frame.buf.ReadByte()
if err != nil {
panic("Could not read byte")
}
delta := b & low_6_offset
frame.loc += uint64(delta) * frame.codeAlignment
}
func advanceloc1(frame *FrameContext) {
delta, err := frame.buf.ReadByte()View on GitHub (pinned to a23773e6c3)
Solutions
- Report it as a bug: a just-succeeded ReadByte followed by UnreadByte should not fail on the internal buffer
- Regenerate/recheck the binary being analyzed for corruption
- Wrap calls in recover() to convert the panic into a parse error
- Upgrade delve — parser robustness fixes may already exist
Example fix
// before
fde, err := frameTable.ExecuteUntilPC(pc) // may panic
// after
func safeLookup(t *frame.FrameDescriptionEntry) (out *frame.FrameDescriptionEntry, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("frame decode failed: %v", r)
}
}()
return t, nil
} Defensive patterns
Strategy: try-catch
Try / catch
func safeCFIParse(parse func()) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("frame decode failed: %v", r)
}
}()
parse()
return nil
} Prevention
- Treat any panic from pkg/dwarf/frame as malformed-input, not a caller bug
- Recover at the outermost frame-parsing boundary and skip affected frames
- Report reproducible panics upstream — these should be error returns
- Test with fuzzed ELF inputs if you embed the parser in your tooling
When it happens
Trigger: Decoding an extended DWARF CFI opcode (DW_CFA_advance_loc family / restore handling) where the last byte read is the opcode argument; only occurs if the byte-slice-backed buffer is mis-positioned or a custom/different buffer type is passed into the frame parser.
Common situations: Practically rare for users; seen when the frame table is constructed over unexpected data, or in fuzzing/corpus testing of pkg/dwarf/frame with malformed inputs.
Related errors
- Could not read from instruction buffer
- Could not read byte
- panic(err)
- Could not parse ULEB128 value
- Could not parse SLEB128 value
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/c7b4ebeae56b894d.
Report an issue: GitHub.