go-delve/delve · warning
changing register %d not implemented
Error message
changing register %d not implemented
What it means
On darwin/amd64, nativeThread.SetReg only implements changing the instruction pointer (AMD64_Rip via setPC). Any other register number returns this 'not implemented' error. It is an explicit API limitation of the darwin backend, not a runtime/kernel fault.
Source
Thrown at pkg/proc/native/registers_darwin_amd64.go:130
}
func (r *Regs) GAddr() (uint64, bool) {
return 0, false
}
// SetPC sets the RIP register to the value specified by `pc`.
func (thread *nativeThread) setPC(pc uint64) error {
kret := C.set_pc(thread.os.threadAct, C.uint64_t(pc))
if kret != C.KERN_SUCCESS {
return fmt.Errorf("could not set pc")
}
return nil
}
// SetReg changes the value of the specified register.
func (thread *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
if regNum != regnum.AMD64_Rip {
return fmt.Errorf("changing register %d not implemented", regNum)
}
return thread.setPC(reg.Uint64Val)
}
func (r *Regs) Get(n int) (uint64, error) {
reg := x86asm.Reg(n)
const (
mask8 = 0x000f
mask16 = 0x00ff
mask32 = 0xffff
)
switch reg {
// 8-bit
case x86asm.AL:
return r.rax & mask8, nil
case x86asm.CL:
return r.rcx & mask8, nilView on GitHub (pinned to a23773e6c3)
Solutions
- Restrict register mutation to Rip on darwin; for other registers use higher-level operations (restart, step)
- Extend SetReg with a Mach thread_set_state path for additional registers and upstream the patch
- Use a Linux target if arbitrary register writes are required by your workflow
Defensive patterns
Strategy: validation
Validate before calling
// before calling SetReg on darwin
if regNum != regnum.AMD64_Rip {
return fmt.Errorf("only Rip can be set on darwin/amd64 (got %d)", regNum)
} Type guard
func canSetRegDarwin(regNum uint64) bool {
return regNum == regnum.AMD64_Rip
} Try / catch
err := thread.SetReg(regNum, reg)
if err != nil && strings.Contains(err.Error(), "not implemented") {
return fmt.Errorf("register %d unsupported on darwin; use restart/step instead", regNum)
} Prevention
- Only set Rip on macOS; avoid full-register restores on darwin backend
- Design workflows around step/restart rather than raw register writes
- Extend via thread_set_state upstream if more registers are needed
When it happens
Trigger: Calling SetReg (directly or via register-restoring machinery such as non-step breakpoint clears or RPC calls) with any register other than Rip on macOS.
Common situations: Restoring full register sets saved earlier; setting variables held in registers; automation/scripts issuing SetReg for arbitrary DWARF register numbers on macOS.
Related errors
- could not set pc
- could not get registers
- could not resume task
- could not attach to %d
- error while waiting for task
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/1f830178508d6612.
Report an issue: GitHub.