go-delve/delve · error
changing register %d not implemented
Error message
changing register %d not implemented
What it means
Delve's Windows ARM64 register writer only implements a fixed set of registers: the general-purpose registers plus V0..V30 float registers. SetReg reaches the default branch when the requested register number is outside the implemented set (e.g. V31, FPSR/FPCR, or other system registers), and throws this placeholder error.
Source
Thrown at pkg/proc/winutil/regs_arm64_arch.go:183
case regnum.ARM64_PC:
ctx.Pc = reg.Uint64Val
return nil
case regnum.ARM64_SP:
ctx.Sp = reg.Uint64Val
return nil
default:
switch {
case regNum >= regnum.ARM64_X0 && regNum <= regnum.ARM64_X0+30:
ctx.Regs[regNum-regnum.ARM64_X0] = reg.Uint64Val
return nil
case regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30:
i := regNum - regnum.ARM64_V0
ctx.FloatRegisters[i].Low = reg.Uint64Val
ctx.FloatRegisters[i].High = 0
return nil
default:
return fmt.Errorf("changing register %d not implemented", regNum)
}
}
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Do not attempt to set V31 or system/FPSR/FPCR registers through this API — they are not implemented on Windows ARM64.
- Restrict register writes to the implemented set: general-purpose registers and V0..V30.
- If the register truly needs modification, extend winutil regs_arm64_arch.go SetReg with a case mapping regNum to the corresponding CONTEXT FloatRegisters or system field.
- Verify the register index with regnum helpers before calling SetReg.
Example fix
// before
i := regNum - regnum.ARM64_V0 // regNum == ARM64_V0+31 -> falls to default
// after
if regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30 {
i := regNum - regnum.ARM64_V0
ctx.FloatRegisters[i].Low = reg.Uint64Val
ctx.FloatRegisters[i].High = 0
return nil
}
return fmt.Errorf("register %s is not settable on windows/arm64", regnum.ARM64ToName(regNum)) Defensive patterns
Strategy: validation
Validate before calling
if regNum == regnum.ARM64_V0+31 || !(regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30) {
return fmt.Errorf("register %d is not settable on windows/arm64", regNum)
} Type guard
func isSettableARM64Reg(regNum int) bool {
return (regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30) || isGPR(regNum)
} Try / catch
if err := thread.SetReg(regNum, reg); err != nil {
var notImpl interface{ Error() string }
if strings.Contains(err.Error(), "not implemented") {
// fall back: skip register or use a read-only view
}
return err
} Prevention
- Only write registers known to be implemented: GPRs and V0..V30 on windows/arm64.
- Never attempt V31, FPCR, or FPSR writes through this API.
- Check Delve's porting notes (Documentation/internal/portnotes.md) for per-OS register support.
- Guard register-write automation with a capability table per OS/arch.
When it happens
Trigger: Calling SetReg on a Windows/arm64 target with regNum not matching any handled case — notably regnum.ARM64_V0+31 (V31), or non-vector/non-GPR registers like FPCR/FPSR that the switch does not enumerate.
Common situations: Tooling that assumes all ARM64 registers are writable; attempts to set V31 (which aliases the zero register ZR in instructions and is excluded from the V0..V30 range); attempts to write floating-point status/control registers during debugging sessions on Windows ARM64.
Related errors
- not implemented
- changing register %d not implemented
- NtQueryInformationThread failed: it returns 0x%x
- LR register is nil during stack switch
- wrong number of bytes for register %s (%d)
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/0b19c584e6fd982e.
Report an issue: GitHub.