go-delve/delve · error
can not set %s
Error message
can not set %s
What it means
After handling general-purpose registers, the amd64 SetReg only supports writing XMM0-XMM15 floating-point/SIMD registers. Any other register number (e.g. x87 st registers, segment descriptor bases, debug registers reachable only through other paths) is rejected with this error.
Source
Thrown at pkg/proc/linutil/regs_amd64_arch.go:218
if p != nil {
if reg.Bytes != nil && len(reg.Bytes) != 8 {
return false, fmt.Errorf("wrong number of bytes for register %s (%d)", regnum.AMD64ToName(regNum), len(reg.Bytes))
}
*p = reg.Uint64Val
return false, nil
}
if r.loadFpRegs != nil {
err := r.loadFpRegs(r)
if err != nil {
return false, err
}
r.loadFpRegs = nil
}
if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {
return false, fmt.Errorf("can not set %s", regnum.AMD64ToName(regNum))
}
reg.FillBytes()
err := r.Fpregset.SetXmmRegister(int(regNum-regnum.AMD64_XMM0), reg.Bytes)
if err != nil {
return false, err
}
return true, nil
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Only call SetReg for registers it supports (GPRs and XMM0-XMM15); reject or no-op unsupported registers in the caller
- Use the appropriate backend API if the register must be modified (e.g. ptrace POKEUSER on a specific offset, or a debugger feature that supports it)
- Verify the register number constant belongs to regnum.AMD64_* and not another architecture
Example fix
// before
thread.SetReg(regnum.AMD64_ST0, reg) // unsupported
// after
if regnum.AMD64_XMM0 <= regNum && regNum <= regnum.AMD64_XMM0+15 {
thread.SetReg(regNum, reg)
} else {
return fmt.Errorf("register %s is not settable via SetReg", regnum.AMD64ToName(regNum))
} Defensive patterns
Strategy: validation
Validate before calling
if regNum < regnum.AMD64_XMM0 || regNum > regnum.AMD64_XMM0+15 {
isGPR := false // check against the supported GPR set first
if !isGPR {
return fmt.Errorf("register %s is not settable", regnum.AMD64ToName(regNum))
}
} Type guard
func isSettableAMD64(regNum regnum.AMD64) bool {
return regNum <= regnum.AMD64_Rflags || (regNum >= regnum.AMD64_XMM0 && regNum <= regnum.AMD64_XMM0+15)
} Try / catch
if err := thread.SetReg(regNum, reg); err != nil {
var unsupported *regUnsupportedError
if strings.Contains(err.Error(), "can not set") {
return fmt.Errorf("skipping non-settable register %s", regnum.AMD64ToName(regNum))
}
return err
} Prevention
- Consult regnum.AMD64 constants and only write documented settable registers
- Treat YMM/ZMM/x87/debug registers as read-only through this API
- Guard register-write features with an architecture capability check
When it happens
Trigger: Calling SetReg on Linux/amd64 with a register number outside the XMM0..XMM0+15 range and outside the general-purpose switch handled earlier (where p was nil and no fallback exists).
Common situations: Attempting to modify AVX YMM/ZMM registers, x87 control registers, or debug registers through the ptrace-backed SetReg path; using a register-number constant from a different architecture by mistake.
Related errors
- could not restore RFLAGS register: %v
- wrong number of bytes for register %s (%d)
- can not change register values of core process
- read out of bounds
- write out of bounds
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/73bac9bfdd5b58e6.
Report an issue: GitHub.