go-delve/delve · error

read out of bounds

Error message

read out of bounds

What it means

compositeMemory backs variables whose bytes come from registers and/or cached memory slices. ReadMemory adjusts the address by the memory base and rejects any read that falls outside the assembled data buffer with 'read out of bounds'. It indicates the requested address/size range is not covered by the pieces (registers or memory slices) that make up this composite view.

Source

Thrown at pkg/proc/mem.go:181

				binary.LittleEndian.PutUint64(buf, piece.Val)
			}
			cmem.data = append(cmem.data, buf[:piece.Size]...)
		default:
			panic("unsupported piece kind")
		}
	}
	paddingBytes := int(size) - len(cmem.data)
	if paddingBytes > 0 && paddingBytes < arch.ptrSize {
		padding := make([]byte, paddingBytes)
		cmem.data = append(cmem.data, padding...)
	}
	return cmem, nil
}

func (mem *compositeMemory) ReadMemory(data []byte, addr uint64) (int, error) {
	addr -= mem.base
	if addr >= uint64(len(mem.data)) || addr+uint64(len(data)) > uint64(len(mem.data)) {
		return 0, errors.New("read out of bounds")
	}
	copy(data, mem.data[addr:addr+uint64(len(data))])
	return len(data), nil
}

func (mem *compositeMemory) WriteMemory(addr uint64, data []byte) (int, error) {
	addr -= mem.base
	if addr >= uint64(len(mem.data)) || addr+uint64(len(data)) > uint64(len(mem.data)) {
		return 0, errors.New("write out of bounds")
	}
	if mem.regs.ChangeFunc == nil {
		for _, piece := range mem.pieces {
			if piece.Kind == op.RegPiece {
				return 0, errors.New("can not write registers")
			}
		}
	}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Re-select the correct goroutine/frame (frame number 0 or a still-live frame) and re-evaluate the variable
  2. Rebuild the binary with -gcflags="all=-N -l" to disable optimizations that produce fragmented locations
  3. If using a core dump, verify it matches the exact binary build; retry evaluation after stepping so the frame is live

Example fix

// before (dlv)
(dlv) frame 7
(dlv) print localVar   // read out of bounds
// after
(dlv) frame 0
(dlv) print localVar
Defensive patterns

Strategy: validation

Validate before calling

// In the debugger, confirm the frame is live before evaluating:
//   (dlv) frame 0
//   (dlv) print localVar
// Reads from returned frames trigger out-of-bounds on composite memory.

Try / catch

v, err := eval(expr)
if err != nil && strings.Contains(err.Error(), "read out of bounds") {
    return fmt.Errorf("variable %s is not available in this frame (optimized or dead frame): %w", expr, err)
}

Prevention

When it happens

Trigger: Any expression evaluation that reads a variable backed by compositeMemory (e.g. a struct assembled from register pieces or a stack-frame-relative variable) where addr or addr+len(data) exceeds the collected data — e.g. evaluating a variable whose DWARF location resolves outside the frame, or reading past the end of a register-assembled value.

Common situations: Stale frame references after the stack changed (evaluating a variable in a returned frame); DWARF location lists mismatching the binary; reading variables in optimized code where Delve mis-assembles pieces; core dumps with missing memory regions.

Related errors


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