{"record":{"id":"9cbe54b7e4db810f","repo":"go-delve/delve","slug":"lr-register-is-nil-during-stack-switch","errorCode":null,"errorMessage":"LR register is nil during stack switch","messagePattern":"LR register is nil during stack switch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/stack.go","lineNumber":356,"sourceCode":"\tit.top = false\n\tit.pc = it.frame.Ret\n\tit.regs = callFrameRegs\n\treturn true\n}\n\nfunc (it *stackIterator) switchToGoroutineStack() error {\n\tif it.g == nil {\n\t\treturn fmt.Errorf(\"nil goroutine when attempting to switch to goroutine stack\")\n\t}\n\tit.systemstack = false\n\tit.top = false\n\tit.pc = it.g.PC\n\tit.regs.Reg(it.regs.SPRegNum).Uint64Val = it.g.SP\n\tit.regs.AddReg(it.regs.BPRegNum, op.DwarfRegisterFromUint64(it.g.BP))\n\tif it.bi.Arch.usesLR {\n\t\tlrReg := it.regs.Reg(it.regs.LRRegNum)\n\t\tif lrReg == nil {\n\t\t\treturn fmt.Errorf(\"LR register is nil during stack switch\")\n\t\t}\n\t\tlrReg.Uint64Val = it.g.LR\n\t}\n\treturn nil\n}\n\n// Frame returns the frame the iterator is pointing at.\nfunc (it *stackIterator) Frame() Stackframe {\n\tit.frame.Bottom = it.atend\n\treturn it.frame\n}\n\n// Err returns the error encountered during stack iteration.\nfunc (it *stackIterator) Err() error {\n\treturn it.err\n}\n\n// frameBase calculates the frame base pseudo-register for DWARF for fn and","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/stack.go#L338-L374","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"null","handlingStrategy":"type-guard","validationCode":"if bi.Arch.usesLR && it.regs.Reg(it.regs.LRRegNum) == nil { return errors.New(\"register set incomplete: LR missing\") }","typeGuard":"func hasLR(regs op.DwarfRegisters, arch proc.Arch) bool { return !arch.usesLR || regs.Reg(regs.LRRegNum) != nil }","tryCatchPattern":"err := iterateStack(g); if err != nil && strings.Contains(err.Error(), \"LR register is nil\") { /* re-collect registers via fresh stop before retry */ }","preventionTips":["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"],"tags":["arm64","registers","stack","link-register"],"backgroundTag":"missing-lr-register","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}