go-delve/delve · error
changing register %d not implemented
Error message
changing register %d not implemented
What it means
The riscv64 SetReg implementation covers integer registers and the F0-F31 floating-point registers; any other register number hits the default branch and is rejected as not implemented.
Source
Thrown at pkg/proc/linutil/regs_riscv64_arch.go:356
}
switch {
case regNum >= regnum.RISCV64_F0 && regNum <= regnum.RISCV64_F31:
if r.loadFpRegs != nil {
err := r.loadFpRegs(r)
r.loadFpRegs = nil
if err != nil {
return false, err
}
}
i := regNum - regnum.RISCV64_F0
reg.FillBytes()
copy(r.Fpregset[8*i:], reg.Bytes)
return true, nil
default:
return false, fmt.Errorf("changing register %d not implemented", regNum)
}
}
// RISCV64PtraceFpRegs is refer to the definition of struct __riscv_d_ext_state in the kernel ptrace.h
type RISCV64PtraceFpRegs struct {
Fregs []byte
Fcsr uint32
}
const _RISCV64_FPREGSET_LENGTH = (32 * 8)
func (fpregs *RISCV64PtraceFpRegs) Decode() (regs []proc.Register) {
for i := 0; i < len(fpregs.Fregs); i += 8 {
name := fmt.Sprintf("F%d", (i / 8))
value := fpregs.Fregs[i : i+8]
regs = proc.AppendBytesRegister(regs, name, value)
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Only write GPRs and F0-F31 via SetReg on riscv64
- Handle FCSR writes through the native backend's ptrace register sets if needed
- Check regnum ranges in the caller before invoking SetReg
Example fix
// before
thread.SetReg(regnum.RISCV64_FCSR, reg) // not implemented
// after
if regnum.RISCV64_F0 <= regNum && regNum <= regnum.RISCV64_F0+31 {
thread.SetReg(regNum, reg)
} else {
return fmt.Errorf("cannot set register %d on riscv64", regNum)
} Defensive patterns
Strategy: validation
Validate before calling
supported := isGPR(regNum) || (regNum >= regnum.RISCV64_F0 && regNum <= regnum.RISCV64_F0+31)
if !supported {
return fmt.Errorf("register %d not settable on riscv64", regNum)
} Type guard
func isSettableRISCV64(regNum uint64) bool {
return isGPR(regNum) || (regNum >= regnum.RISCV64_F0 && regNum <= regnum.RISCV64_F0+31)
} Try / catch
if _, err := thread.SetReg(regNum, reg); err != nil {
if strings.Contains(err.Error(), "not implemented") {
return fmt.Errorf("riscv64 register %d cannot be modified", regNum)
}
return err
} Prevention
- Only write integer and F0-F31 registers on riscv64
- Treat FCSR/CSRs as read-only through SetReg
- Validate regnum against the riscv64 package constants
When it happens
Trigger: Calling SetReg on Linux/riscv64 with a register number outside the implemented GPR set and outside RISCV64_F0..F0+31 (e.g. FCSR, CSR registers).
Common situations: Attempting to write riscv64 control/status registers via the debugger; register constants from another ISA leaking into the riscv64 path.
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/1ac3edb7f9313c77.
Report an issue: GitHub.