go-delve/delve · error
changing register %d not implemented
Error message
changing register %d not implemented
What it means
The arm64 SetReg implementation covers only a fixed subset of registers (GPRs and V0-V31 vector registers). Any register number falling through to the default case has no write path implemented, so the request is rejected.
Source
Thrown at pkg/proc/linutil/regs_arm64_arch.go:177
r.Regs.Regs[regNum-regnum.ARM64_X0] = reg.Uint64Val
return false, nil
case regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+30:
if r.loadFpRegs != nil {
err := r.loadFpRegs(r)
r.loadFpRegs = nil
if err != nil {
return false, err
}
}
i := regNum - regnum.ARM64_V0
reg.FillBytes()
copy(r.Fpregset[16*i:], reg.Bytes)
return true, nil
default:
return false, fmt.Errorf("changing register %d not implemented", regNum)
}
}
}
type ARM64PtraceFpRegs struct {
Vregs []byte
Fpsr uint32
Fpcr uint32
}
const _ARM_FP_REGS_LENGTH = 512
func (fpregs *ARM64PtraceFpRegs) Decode() (regs []proc.Register) {
for i := 0; i < len(fpregs.Vregs); i += 16 {
regs = proc.AppendBytesRegister(regs, fmt.Sprintf("V%d", i/16), fpregs.Vregs[i:i+16])
}
return
}View on GitHub (pinned to a23773e6c3)
Solutions
- Restrict register writes to GPRs and V0-V31 on arm64
- Handle FPSR/FPCR writes through ptrace GETFPREGS/SETFPREGS at the native backend level if needed
- Verify the regnum constant is a valid ARM64 register for the intended set
Example fix
// before
thread.SetReg(regnum.ARM64_FPSR, reg) // not implemented
// after
if regnum.ARM64_V0 <= regNum && regNum <= regnum.ARM64_V0+31 {
thread.SetReg(regNum, reg)
} else {
return fmt.Errorf("cannot set register %d on arm64", regNum)
} Defensive patterns
Strategy: validation
Validate before calling
supported := regNum <= regnum.ARM64_R30 || (regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+31)
if !supported {
return fmt.Errorf("register %d not settable on arm64", regNum)
} Type guard
func isSettableARM64(regNum uint64) bool {
return regNum <= 30 || (regNum >= regnum.ARM64_V0 && regNum <= regnum.ARM64_V0+31)
} Try / catch
if _, err := thread.SetReg(regNum, reg); err != nil {
if strings.Contains(err.Error(), "not implemented") {
return fmt.Errorf("arm64 register %d cannot be modified", regNum)
}
return err
} Prevention
- Only write GPRs and V0-V31 on arm64
- Treat FPSR/FPCR/system registers as read-only unless the backend adds support
- Test register writes per-architecture before enabling the feature in tooling
When it happens
Trigger: Calling SetReg on Linux/arm64 with a register number that is neither a handled general-purpose register nor within ARM64_V0..V0+31 (e.g. FPSR, FPCR, or a bogus/out-of-range regnum).
Common situations: Trying to modify arm64 floating-point status/control registers or system registers via the debugger; porting code that assumed x86-style full register writability.
Related errors
- could not restore registers: %v
- wrong number of bytes for register %s (%d)
- changing register %d not implemented
- changing register %d not implemented
- changing register %d not implemented
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/dc50fb71ba6f5cc1.
Report an issue: GitHub.