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, nil

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Restrict register mutation to Rip on darwin; for other registers use higher-level operations (restart, step)
  2. Extend SetReg with a Mach thread_set_state path for additional registers and upstream the patch
  3. 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

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


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/1f830178508d6612. Report an issue: GitHub.