go-delve/delve · error
LR register is nil during stack switch
Error message
LR register is nil during stack switch
What it means
On architectures that use a link register (arm64, ppc64le, riscv64, loong64, and 386 on some paths) the return address lives in the LR register. When switching to the goroutine stack, Delve must write g.LR into the LR register; if the register set has no LR slot the switch fails because the return address cannot be restored.
Source
Thrown at pkg/proc/stack.go:356
it.top = false
it.pc = it.frame.Ret
it.regs = callFrameRegs
return true
}
func (it *stackIterator) switchToGoroutineStack() error {
if it.g == nil {
return fmt.Errorf("nil goroutine when attempting to switch to goroutine stack")
}
it.systemstack = false
it.top = false
it.pc = it.g.PC
it.regs.Reg(it.regs.SPRegNum).Uint64Val = it.g.SP
it.regs.AddReg(it.regs.BPRegNum, op.DwarfRegisterFromUint64(it.g.BP))
if it.bi.Arch.usesLR {
lrReg := it.regs.Reg(it.regs.LRRegNum)
if lrReg == nil {
return fmt.Errorf("LR register is nil during stack switch")
}
lrReg.Uint64Val = it.g.LR
}
return nil
}
// Frame returns the frame the iterator is pointing at.
func (it *stackIterator) Frame() Stackframe {
it.frame.Bottom = it.atend
return it.frame
}
// Err returns the error encountered during stack iteration.
func (it *stackIterator) Err() error {
return it.err
}
// frameBase calculates the frame base pseudo-register for DWARF for fn andView on GitHub (pinned to a23773e6c3)
Solutions
- Update Delve to the latest version (arch-specific register handling fixes land frequently)
- Re-collect registers with a fresh stop of the thread
- Check DWARF info integrity of the binary (rebuild without -ldflags "-s -w")
- File a bug with the Go version, OS/arch, and stack dump if reproducible
Example fix
null
Defensive patterns
Strategy: type-guard
Validate before calling
if bi.Arch.usesLR && it.regs.Reg(it.regs.LRRegNum) == nil { return errors.New("register set incomplete: LR missing") } Type guard
func hasLR(regs op.DwarfRegisters, arch proc.Arch) bool { return !arch.usesLR || regs.Reg(regs.LRRegNum) != nil } Try / catch
err := iterateStack(g); if err != nil && strings.Contains(err.Error(), "LR register is nil") { /* re-collect registers via fresh stop before retry */ } Prevention
- Keep Delve current on ARM64/PPC64LE/RISCV64 platforms
- Ensure DWARF info is present in debugged binaries
- Re-read registers after any process state change
- Report persistent occurrences with arch + Go version to Delve maintainers
When it happens
Trigger: switchToGoroutineStack called on an usesLR architecture where the DWARF register set (it.regs) lacks an entry for the LR register number — usually after register set was reconstructed from incomplete DWARF rules or a broken context.
Common situations: Debugging on ARM64/PPC64LE/RISCV64 when register reconstruction skipped LR (e.g. certain DWARF CFI edge cases, leaf-function optimizations); corrupted or minimal register context from a core dump; Delve arch/DWARF mismatches after Go runtime updates.
Related errors
- changing register %d not implemented
- changing register %d not implemented
- can not change register values of core process
- can not run under Rosetta, check that the installed build of
- read out of bounds
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/9cbe54b7e4db810f.
Report an issue: GitHub.