{"record":{"id":"e4659e9f7d8d9702","repo":"go-delve/delve","slug":"error-calling-traverse-on-dynamic-children","errorCode":null,"errorMessage":"error calling traverse on dynamic children","messagePattern":"error calling traverse on dynamic children","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/debugger/debugger.go","lineNumber":1521,"sourceCode":"\n\t\t\t\t\t// Extract address from the decoded instruction's destination location\n\t\t\t\t\tvar addr uint64\n\t\t\t\t\tif len(disasm) > 0 && disasm[0].DestLoc != nil {\n\t\t\t\t\t\taddr = disasm[0].DestLoc.PC\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"failed to extract call destination from instruction at PC %#x\", pc)\n\t\t\t\t\t}\n\t\t\t\t\tfn := tgt.BinInfo().PCToFunc(addr)\n\t\t\t\t\tif fn == nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"PCToFunc returned nil\")\n\t\t\t\t\t}\n\t\t\t\t\terr = createFunctionTracepoints(d, fn.Name, rootstr, followCalls)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"error creating tracepoint in function %s\", fn.Name)\n\t\t\t\t\t}\n\t\t\t\t\tdynchildren, err := d.traverse(t, fn, sdepth+1, followCalls, rootstr)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, fmt.Errorf(\"error calling traverse on dynamic children\")\n\t\t\t\t\t}\n\t\t\t\t\tfor _, child := range dynchildren {\n\t\t\t\t\t\terr := createFunctionTracepoints(d, child, rootstr, followCalls)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn false, fmt.Errorf(\"error creating tracepoint in function %s\", child)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false, nil\n\t\t\t\t}\n\t\t\t\tfor _, dynBrklet := range dynbp.Breaklets {\n\t\t\t\t\tdynBrklet.SetCallback(dynCallback)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif instr.IsCall() && instr.DestLoc != nil && instr.DestLoc.Fn != nil {\n\t\t\t\tcf := instr.DestLoc.Fn\n\t\t\t\tif (strings.HasPrefix(cf.Name, \"runtime.\") || strings.HasPrefix(cf.Name, \"runtime/internal\")) && cf.Name != \"runtime.deferreturn\" && cf.Name != \"runtime.gorecover\" && cf.Name != \"runtime.gopanic\" {\n\t\t\t\t\tcontinue","sourceCodeStart":1503,"sourceCodeEnd":1539,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/debugger/debugger.go#L1503-L1539","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nreturn false, fmt.Errorf(\"error calling traverse on dynamic children\")\n// after (keep the causal chain)\nreturn false, fmt.Errorf(\"error calling traverse on dynamic children: %w\", err)","handlingStrategy":"try-catch","validationCode":"// bound traversal cost before tracing: estimate call-graph breadth at depth N\n// and reject excessive depths up front\nmaxDepth := 3\nif *followCallsFlag > maxDepth {\n\tlog.Fatalf(\"--follow-calls=%d is too deep; recursive traverse likely to fail; use <= %d\", *followCallsFlag, maxDepth)\n}","typeGuard":"func isTraverseError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"error calling traverse on dynamic children\")\n}","tryCatchPattern":"if err := runTrace(); err != nil {\n\tif isTraverseError(err) {\n\t\tlog.Println(\"recursive traversal failed; retrying with reduced depth\")\n\t\treturn runTrace(TraceOpts{FollowCalls: currentDepth - 1})\n\t}\n\treturn err\n}","preventionTips":["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."],"tags":["debugger","ebpf","recursion","follow-calls"],"backgroundTag":"trace-traversal-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}