go-delve/delve · critical
Could not read from instruction buffer
Error message
Could not read from instruction buffer
What it means
executeDwarfInstruction panics when the DWARF CFI instruction buffer is exhausted mid-decode: buf.ReadByte() failed so there is no opcode byte to dispatch on. This indicates a truncated or malformed .eh_frame/.debug_frame section (or a decode offset bug), and the library surfaces it as a panic rather than an error return.
Source
Thrown at pkg/dwarf/frame/table.go:205
frame.buf.Truncate(0)
frame.buf.Write(instructions)
// We only need to execute the instructions until
// ctx.loc > ctx.address (which is the address we
// are currently at in the traced process).
for frame.address >= frame.loc && frame.buf.Len() > 0 && frame.err == nil {
executeDwarfInstruction(frame)
}
return frame.err
}
func executeDwarfInstruction(frame *FrameContext) {
if frame.err != nil {
return
}
instruction, err := frame.buf.ReadByte()
if err != nil {
panic("Could not read from instruction buffer")
}
if instruction == DW_CFA_nop {
return
}
fn := lookupFunc(instruction, frame.buf)
if fn == nil {
frame.err = fmt.Errorf("encountered an unexpected DWARF CFA opcode: %#v", instruction)
return
}
fn(frame)
}
func lookupFunc(instruction byte, buf *bytes.Buffer) instruction {
const high_2_bits = 0xc0View on GitHub (pinned to a23773e6c3)
Solutions
- Regenerate or re-obtain the binary/core file and retry — corruption is the usual cause
- Verify the executable and core dump come from the same build and are complete (checksums)
- File a bug with the offending binary attached: a panic here is a parser robustness defect and should be recovered/converted to an error upstream
- As a caller, wrap ExecuteUntilPC in a recover() until the parser is hardened
Example fix
// caller-side mitigation
// before
fde, err := table.ExecuteUntilPC(pc)
// after
func safeExecute(t *frame.Table, pc uint64) (res *frame.FrameDescriptionEntry, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("malformed frame data: %v", r)
}
}()
return t.ExecuteUntilPC(pc)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify inputs before parsing frame data:
// 1) binary and core exist and are non-empty
fi, err := os.Stat(corePath)
if err != nil || fi.Size() == 0 { return fmt.Errorf("missing/empty core file") }
// 2) match ELF build IDs between executable and core
// (mismatches commonly produce truncated/misread DWARF sections) Try / catch
func safeExecute(t *frame.Table, pc uint64) (res *frame.FrameDescriptionEntry, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("malformed CFI stream: %v", r)
}
}()
return t.ExecuteUntilPC(pc)
} Prevention
- Always pair core dumps with the exact matching executable build
- Validate downloaded binaries (checksum/build ID) before analysis
- Wrap pkg/dwarf/frame entry points in recover() — they panic on malformed input
- Report panics with the offending binary to delve maintainers
When it happens
Trigger: Parsing a frame description entry whose CIE/FDE length fields are inconsistent with the actual section data; a corrupt or hand-trimmed binary; a truncated core dump or stripped binary where the frame section was cut short.
Common situations: Analyzing core dumps from mismatched or partially written files; binaries produced by non-Go toolchains or linkers that emit unusual FDE padding; loading symbols from a binary corrupted during download/transfer.
Related errors
- Could not unread byte
- 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/676df23edb961e12.
Report an issue: GitHub.