go-delve/delve · error
could not restore RFLAGS register: %v
Error message
could not restore RFLAGS register: %v
What it means
On amd64, the tail of runtime.debugCallV2 corrupts the RFLAGS register, so Delve restores it one extra time from the saved register set. This error is raised when writing the RFLAGS register back to the thread fails.
Source
Thrown at pkg/proc/fncall.go:883
if err := setPC(thread, pc); err != nil {
fncall.err = fmt.Errorf("could not restore PC: %v", err)
}
if err := setSP(thread, sp); err != nil {
fncall.err = fmt.Errorf("could not restore SP: %v", err)
}
fncallLog("stepping thread %d", thread.ThreadID())
if err := stepInstructionOut(callScope.callCtx.grp, p, thread, fncall.debugCallName, fncall.debugCallName); err != nil {
fncall.err = fmt.Errorf("could not step out of %s: %v", fncall.debugCallName, err)
}
if bi.Arch.Name == "amd64" {
// The tail of debugCallV2 corrupts the state of RFLAGS, we must restore
// it one extra time after stepping out of it.
// See https://github.com/go-delve/delve/issues/2985 and
// TestCallInjectionFlagCorruption
rflags := bi.Arch.RegistersToDwarfRegisters(0, fncall.savedRegs).Uint64Val(regnum.AMD64_Rflags)
err := thread.SetReg(regnum.AMD64_Rflags, op.DwarfRegisterFromUint64(rflags))
if err != nil {
fncall.err = fmt.Errorf("could not restore RFLAGS register: %v", err)
}
}
return true
case debugCallRegReadReturn: // 1
// read return arguments from stack
stack.callInjectionContinue = true
if fncall.panicvar != nil || fncall.err != nil {
break
}
retScope, err := ThreadScope(p, thread)
if err != nil {
fncall.err = fmt.Errorf("could not get return values: %v", err)
break
}
// pretend we are still inside the function we called
fakeFunctionEntryScope(retScope, fncall.fn, int64(regs.SP()), regs.SP()-uint64(bi.Arch.PtrSize()))View on GitHub (pinned to a23773e6c3)
Solutions
- Verify the process is alive; restart the session if not
- Retry the call injection — transient register-write failures may clear
- Use a backend that supports SetReg (native) rather than core dumps
- Report persistent amd64 RFLAGS write failures to Delve issue tracker (see issue #2985)
Defensive patterns
Strategy: try-catch
Validate before calling
// amd64 only: confirm backend supports SetReg before call injection // (native backend does; core dumps do not)
Try / catch
err := dbg.CallFunction(scope, fn, args)
if err != nil && strings.Contains(err.Error(), "could not restore RFLAGS") {
// flags may be stale: restart session or re-issue the call
}
Prevention
- Use a writable backend (native) on amd64 for injected calls
- Keep the process alive through the whole call protocol
- Retry once — RFLAGS restore failures are often transient
- See delve issue #2985 for known RFLAGS corruption handling
When it happens
Trigger: funcCallStep, on the amd64 path after stepping out of debugCallV2, calls thread.SetReg(regnum.AMD64_Rflags, ...) and it returns an error.
Common situations: Thread died between the step-out and the register write; ptrace/GETREGSET failures on Linux; gdbserial backends that reject partial register writes; core dump backends that are read-only.
Related errors
- could not restore registers: %v
- could not restore PC: %v
- could not restore SP: %v
- wrong number of bytes for register %s (%d)
- can not set %s
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/b4a4775fda059dc7.
Report an issue: GitHub.