go-delve/delve · error
error calling traverse on dynamic children
Error message
error calling traverse on dynamic children
What it means
After tracing the resolved dynamic callee, Delve recursively calls d.traverse on it to discover its own callees (respecting the follow-calls depth). This error is returned when that recursive traverse fails. Because fmt.Errorf lacks %w, the original cause (disassembly failure, breakpoint setup failure inside the child function) is swallowed, making diagnosis hard.
Source
Thrown at service/debugger/debugger.go:1521
// 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)
if fn == nil {
return false, fmt.Errorf("PCToFunc returned nil")
}
err = createFunctionTracepoints(d, fn.Name, rootstr, followCalls)
if err != nil {
return false, fmt.Errorf("error creating tracepoint in function %s", fn.Name)
}
dynchildren, err := d.traverse(t, fn, sdepth+1, followCalls, rootstr)
if err != nil {
return false, fmt.Errorf("error calling traverse on dynamic children")
}
for _, child := range dynchildren {
err := createFunctionTracepoints(d, child, rootstr, followCalls)
if err != nil {
return false, fmt.Errorf("error creating tracepoint in function %s", child)
}
}
return false, nil
}
for _, dynBrklet := range dynbp.Breaklets {
dynBrklet.SetCallback(dynCallback)
}
}
if instr.IsCall() && instr.DestLoc != nil && instr.DestLoc.Fn != nil {
cf := instr.DestLoc.Fn
if (strings.HasPrefix(cf.Name, "runtime.") || strings.HasPrefix(cf.Name, "runtime/internal")) && cf.Name != "runtime.deferreturn" && cf.Name != "runtime.gorecover" && cf.Name != "runtime.gopanic" {
continueView on GitHub (pinned to a23773e6c3)
Solutions
- Lower the --follow-calls depth to avoid recursing into problematic functions.
- Check the debugger log (dlv --log --log-output=debug) for the underlying traverse error that this wrapper hides.
- Ensure the target stays alive for the whole traversal (keep process under load before tracepoints are installed).
- If modifying Delve, wrap the error: fmt.Errorf("error calling traverse on dynamic children: %w", err) so the root cause propagates.
Example fix
// before
return false, fmt.Errorf("error calling traverse on dynamic children")
// after (keep the causal chain)
return false, fmt.Errorf("error calling traverse on dynamic children: %w", err) Defensive patterns
Strategy: try-catch
Validate before calling
// bound traversal cost before tracing: estimate call-graph breadth at depth N
// and reject excessive depths up front
maxDepth := 3
if *followCallsFlag > maxDepth {
log.Fatalf("--follow-calls=%d is too deep; recursive traverse likely to fail; use <= %d", *followCallsFlag, maxDepth)
} Type guard
func isTraverseError(err error) bool {
return err != nil && strings.Contains(err.Error(), "error calling traverse on dynamic children")
} Try / catch
if err := runTrace(); err != nil {
if isTraverseError(err) {
log.Println("recursive traversal failed; retrying with reduced depth")
return runTrace(TraceOpts{FollowCalls: currentDepth - 1})
}
return err
} Prevention
- Start with --follow-calls=1 or 2 and increase only as needed.
- Enable dlv --log --log-output=debug to capture the underlying traverse failure this wrapper hides.
- Avoid tracing functions with dense dynamic-call cycles.
- Keep the target process alive until tracepoint installation completes.
When it happens
Trigger: d.traverse(t, fn, sdepth+1, followCalls, rootstr) returned a non-nil error inside the dynCallback while expanding dynamic call children during eBPF follow-calls tracing.
Common situations: Deep --follow-calls values recursing into functions that fail to disassemble (assembly-heavy or runtime functions); breakpoint insertion failures in child functions; cycles of dynamic calls exhausting probe resources; target process exiting mid-traversal.
Related errors
- failed to disassemble instruction: %w
- PCToFunc returned nil
- ebpf composite memory: %w
- traverse failed with error %w
- disassemble failed with error %w
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/e4659e9f7d8d9702.
Report an issue: GitHub.