go-delve/delve · error

could not read %d bytes from register %d (size: %d), also er

Error message

could not read %d bytes from register %d (size: %d), also error loading floating point registers: %v

What it means

This error is thrown by newCompositeMemory in pkg/proc/mem.go when evaluating a DWARF location expression whose pieces read from CPU registers. A DWARF piece requested more bytes (piece.Size) than the register returned by regs.Bytes(piece.Val) actually provides (len(reg)). If the floating-point register load also failed, the underlying FloatLoadError is appended to give the real root cause.

Source

Thrown at pkg/proc/mem.go:144

	if cm != nil {
		cm.base = fakeAddressUnresolv
	}
	return cm, err
}

func newCompositeMemory(mem MemoryReadWriter, arch *Arch, regs op.DwarfRegisters, pieces []op.Piece, size int64) (*compositeMemory, error) {
	cmem := &compositeMemory{realmem: mem, arch: arch, regs: regs, pieces: pieces, data: []byte{}}
	for i := range pieces {
		piece := &pieces[i]
		switch piece.Kind {
		case op.RegPiece:
			reg := regs.Bytes(piece.Val)
			if piece.Size == 0 && i == len(pieces)-1 {
				piece.Size = len(reg)
			}
			if piece.Size > len(reg) {
				if regs.FloatLoadError != nil {
					return nil, fmt.Errorf("could not read %d bytes from register %d (size: %d), also error loading floating point registers: %v", piece.Size, piece.Val, len(reg), regs.FloatLoadError)
				}
				return nil, fmt.Errorf("could not read %d bytes from register %d (size: %d)", piece.Size, piece.Val, len(reg))
			}
			cmem.data = append(cmem.data, reg[:piece.Size]...)
		case op.AddrPiece:
			buf := make([]byte, piece.Size)
			if _, err := mem.ReadMemory(buf, piece.Val); err != nil {
				return nil, fmt.Errorf("could not read %d bytes from address %#x: %v", piece.Size, piece.Val, err)
			}
			cmem.data = append(cmem.data, buf...)
		case op.ImmPiece:
			buf := piece.Bytes
			if buf == nil {
				sz := max(piece.Size, 8)
				if piece.Size == 0 && i == len(pieces)-1 {
					piece.Size = arch.PtrSize() // DWARF doesn't say what this should be
				}
				buf = make([]byte, sz)

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Inspect regs.FloatLoadError in the returned error — fix the underlying floating point register load failure first (OS support, ptrace permissions, core dump completeness).
  2. Re-evaluate the variable after the thread is stopped at a point where FP registers are available (stepping out of the signal/syscall context that lost them).
  3. Avoid evaluating variables whose DWARF location places them in XMM registers when using backends that cannot read them (e.g. eBPF uprobes).
  4. Update Delve / OS kernel to a version that supports loading FP registers for this architecture.

Example fix

// before: evaluating a double living in xmm0 with FP regs unavailable
// err: could not read 8 bytes from register 17 (size: 0), also error loading floating point registers: ...
// after: check FloatLoadError first and degrade gracefully
v, err := evalScope.EvalVariable(name)
if err != nil && strings.Contains(err.Error(), "floating point registers") {
    v = &proc.Variable{Name: name, Unreadable: "FP registers unavailable"}
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before evaluating a variable whose location is a register piece:
if regs.FloatLoadError != nil {
    return fmt.Errorf("skip evaluation: FP registers unavailable: %w", regs.FloatLoadError)
}
for _, p := range pieces {
    if p.Size > len(regs.Bytes(p.Val)) { return fmt.Errorf("piece %d needs %d bytes, reg has %d", p.Val, p.Size, len(regs.Bytes(p.Val))) }
}

Type guard

func pieceFitsInRegister(regs proc.Registers, piece dwarf.RegisterPiece) bool {
    return piece.Size <= len(regs.Bytes(piece.Val))
}

Try / catch

v, err := scope.EvalVariable(name)
if err != nil && strings.Contains(err.Error(), "could not read ") && strings.Contains(err.Error(), "register ") {
    // degrade: mark variable unreadable instead of failing the whole session
    v = &proc.Variable{Name: name, Unreadable: err.Error()}
}

Prevention

When it happens

Trigger: Calling CreateCompositeMemory (directly or via variable evaluation) on a DWARF expression containing op.RegisterPiece entries where piece.Size exceeds the register width — typically when FP/SSE registers (regnum >= 17) could not be loaded, so regs.Bytes returns an empty/short buffer while the piece still demands e.g. 16 bytes.

Common situations: Debugging on targets where the OS ptrace interface fails to return XSAVE/FP registers; evaluating variables of float/complex types whose value lives in XMM registers; core dumps or remote sessions with incomplete register sets; architectures/OS combos with buggy register backends.

Related errors


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