go-delve/delve · error

could not set register %s: wrong size, expected %d got %d

Error message

could not set register %s: wrong size, expected %d got %d

What it means

SetReg found the register, but the value supplied by Delve has a byte length different from the stub-reported register size (gdbreg.value). The write is refused with this error specifying expected vs got sizes.

Source

Thrown at pkg/proc/gdbserial/gdbserver.go:2104

	if !ok && t.p.bi.Arch.Name == "arm64" && regName == "x30" {
		gdbreg, ok = t.regs.regs["lr"]
	}
	if !ok && regName == "rflags" {
		// rr has eflags instead of rflags
		regName = "eflags"
		gdbreg, ok = t.regs.regs[regName]
		if ok {
			reg.FillBytes()
			reg.Bytes = reg.Bytes[:4]
		}
	}
	if !ok {
		return fmt.Errorf("could not set register %s: not found", regName)
	}
	reg.FillBytes()

	wrongSizeErr := func(n int) error {
		return fmt.Errorf("could not set register %s: wrong size, expected %d got %d", regName, n, len(reg.Bytes))
	}

	if len(reg.Bytes) == len(gdbreg.value) {
		copy(gdbreg.value, reg.Bytes)
		err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
		if err != nil {
			return err
		}
		if t.p.conn.workaroundReg != nil && len(gdbreg.value) > 16 {
			// This is a workaround for a bug in debugserver where register writes (P
			// packet) on AVX-2 and AVX-512 registers are ignored unless they are
			// followed by a write to an AVX register.
			// See:
			//  Issue #2767
			//  https://bugs.llvm.org/show_bug.cgi?id=52362
			reg := t.regs.gdbRegisterNew(t.p.conn.workaroundReg)
			return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
		}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Ensure the remote stub and the inferior architecture match (no 32-bit inferior on stub built for different register layout)
  2. Update Delve and the stub so register sizes come from the same target.xml
  3. Check the expected/got sizes in the message to identify which register and size mismatch and avoid writing it
  4. If writing a 64-bit register from 32-bit-derived data, pad the value to the stub's declared size
Defensive patterns

Strategy: validation

Validate before calling

// size-check before writing:
sizeOK := func(reg *proc.Register, gdbregValueLen int) bool {
    return len(reg.Bytes) == gdbregValueLen
}

Try / catch

err := thread.SetReg(reg)
if err != nil && strings.Contains(err.Error(), "wrong size") {
    // pad or truncate reg.Bytes to the stub-declared size and retry
    return fmt.Errorf("register size mismatch: %w", err)
}

Prevention

When it happens

Trigger: Writing a register where the computed byte slice length disagrees with the stub's register size — commonly after the special-case truncation to 4 bytes (for 32-bit-compatible regs on 64-bit stubs) when the stub's declared size is neither the full nor the truncated size.

Common situations: Mixed 32/64-bit debugging where the stub declares a different register width than Delve's architecture expects; lldb-server/debugserver quirks where a register is reported at one size but must be written at another; architecture mapping bugs for less common targets (ppc64le, riscv64, loong64).

Related errors


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