go-delve/delve · warning
registers inside callback returned err
Error message
registers inside callback returned err
What it means
Error produced inside the dynamic-call breakpoint callback when reading the thread's CPU registers (th.Registers()) fails. Registers are needed to disassemble the pending call instruction and extract its runtime destination; without them the dynamic call target cannot be resolved and the callback aborts with this error.
Source
Thrown at service/debugger/debugger.go:1493
// calculated by referring to the stack and the mechanism is similar to that
// used in pkg/terminal/command.go:printTraceOutput
rootindex := -1
for i := len(rawlocs) - 1; i >= 0; i-- {
if rawlocs[i].Call.Fn.Name == rootstr {
if rootindex == -1 {
rootindex = i
break
}
}
}
sdepth := rootindex + 1
if sdepth+1 > followCalls {
return false, nil
}
regs, err := th.Registers()
if err != nil {
return false, fmt.Errorf("registers inside callback returned err")
}
// Disassemble the instruction at the current PC to get the call destination
pc := instr.Loc.PC
maxInstLen := uint64(tgt.BinInfo().Arch.MaxInstructionLength())
disasm, err := proc.Disassemble(t.Memory(), regs, t.Breakpoints(), tgt.BinInfo(), pc, pc+maxInstLen)
if err != nil {
return false, fmt.Errorf("failed to disassemble instruction: %w", err)
}
// Extract address from the decoded instruction's destination location
var addr uint64
if len(disasm) > 0 && disasm[0].DestLoc != nil {
addr = disasm[0].DestLoc.PC
} else {
return false, fmt.Errorf("failed to extract call destination from instruction at PC %#x", pc)
}
fn := tgt.BinInfo().PCToFunc(addr)View on GitHub (pinned to a23773e6c3)
Solutions
- Re-run the trace — this is often a transient thread-lifetime race.
- Reduce followCalls so fewer dynamic breakpoints/callbacks fire.
- Keep the process alive longer around traced calls (e.g. add a final breakpoint or sleep in the fixture) so threads don't exit mid-callback.
- Check OS-level debugger health (ptrace permissions, yama/ptrace_scope, thread limits).
- Update Delve; callback robustness in follow-calls tracing continues to be improved.
Example fix
// before
// fixture goroutine calls the traced function and exits immediately
func worker() { traced() }
// after
func worker() { traced(); runtime.Gosched() } // keep thread alive past the call Defensive patterns
Strategy: retry
Validate before calling
// ensure the thread is stopped and alive before running follow-calls tracing
state, err := client.GetState()
if err != nil || state.Exited || state.CurrentThread == nil {
return fmt.Errorf("no live thread to trace: %v", err)
} Try / catch
_, err := client.Functions(filter, followCalls)
if err != nil && strings.Contains(err.Error(), "registers inside callback") {
// transient thread-exit race: retry once, then fall back to flat list
if _, err2 := client.Functions(filter, followCalls-1); err2 != nil {
_, _ = client.Functions(filter, 0)
}
} Prevention
- Keep traced goroutines alive past the call site to avoid register-read races.
- Run the debugger with adequate ptrace permissions (ptrace_scope, CAP_SYS_PTRACE).
- Reduce followCalls so fewer dynamic callbacks execute.
- Avoid attaching to threads that are about to exit (waitgroup/sync around traced calls).
- Check OS thread limits and dmesg for ptrace failures if reproducible.
When it happens
Trigger: Callback fired on a dynamic call breakpoint during Functions(filter, followCalls>0) trace setup, and th.Registers() fails because the thread has exited between breakpoint hit and callback, the OS ptrace GETREGS call failed (thread in unexpected state, zombie), or the backend (gdbserial/core) cannot supply register state at that moment.
Common situations: Multi-threaded programs where the hit thread exits immediately after the call instruction; process crash/exit racing the trace; Windows/remote backends with transient register-read failures; core dumps being stepped incorrectly.
Related errors
- write out of bounds
- can not write registers
- could not restore registers: %v
- wrong number of bytes for register %s (%d)
- changing register %d not implemented
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/87fd74c1e34ba781.
Report an issue: GitHub.