go-delve/delve · error

can not set register %s

Error message

can not set register %s

What it means

On Windows amd64, only general-purpose registers (via CONTEXT pointer) and Rflags are directly settable; other register numbers are accepted only if they fall in the XMM0..XMM0+15 range. Any other register number (e.g. debug registers, segment selectors, FPU control regs) cannot be set and yields this error.

Source

Thrown at pkg/proc/winutil/regs_amd64_arch.go:339

		p = &ctx.R13
	case regnum.AMD64_R14:
		p = &ctx.R14
	case regnum.AMD64_R15:
		p = &ctx.R15
	case regnum.AMD64_Rip:
		p = &ctx.Rip
	}

	if p != nil {
		if reg.Bytes != nil && len(reg.Bytes) != 8 {
			return fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes))
		}
		*p = reg.Uint64Val
	} else if regNum == regnum.AMD64_Rflags {
		ctx.EFlags = uint32(reg.Uint64Val)
	} else {
		if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {
			return fmt.Errorf("can not set register %s", regnum.AMD64ToName(regNum))
		}
		reg.FillBytes()
		if len(reg.Bytes) > 16 {
			return fmt.Errorf("too many bytes when setting register %s", regnum.AMD64ToName(regNum))
		}
		copy(ctx.FltSave.XmmRegisters[(regNum-regnum.AMD64_XMM0)*16:], reg.Bytes)
	}
	return nil
}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Restrict writes to GP registers, Rflags, and XMM0-XMM15 on Windows/amd64; skip others gracefully
  2. Use the Windows debug API (SetThreadContext with proper CONTEXT flags) directly for DR/segment registers outside Delve
  3. Set a hardware breakpoint via Delve's breakpoint API instead of writing debug registers
  4. Check regnum values before calling: reject AMD64_XMM0..+15 only, or GP, else no-op

Example fix

// before
setReg(regnum.AMD64_Dr0, val) // can not set register DR0
// after
if (regNum >= regnum.AMD64_Rax && regNum <= regnum.AMD64_R15) || regNum == regnum.AMD64_Rip ||
   (regNum >= regnum.AMD64_XMM0 && regNum <= regnum.AMD64_XMM0+15) {
    setReg(regNum, val)
}
Defensive patterns

Strategy: validation

Validate before calling

// Whitelist settable registers on Windows amd64 before writing
settable := func(n regnum.REGNUM) bool {
    gp := n >= regnum.AMD64_Rax && n <= regnum.AMD64_Rip
    xmm := n >= regnum.AMD64_XMM0 && n <= regnum.AMD64_XMM0+15
    return gp || xmm
}

Prevention

When it happens

Trigger: Attempting to set a register by number outside the GP + Rflags + XMM sets on a Windows/amd64 target — e.g. trying to write a debug register (DR0-DR7), segment registers, or ST/MMX registers through SetRegs.

Common situations: Tooling that sets register state generically across platforms (Linux allows some registers Windows doesn't); restoring full register contexts including x87 state; attempting to write DR registers for hardware breakpoints.

Related errors


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