{"record":{"id":"c730a063858247a9","repo":"go-delve/delve","slug":"unexpected-cfa-rule-d-at-uprobe-pc-x","errorCode":null,"errorMessage":"unexpected CFA rule %d at uprobe PC %#x","messagePattern":"unexpected CFA rule (.+?) at uprobe PC %#x","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/breakpoints.go","lineNumber":713,"sourceCode":"// This offset is used as inputRegs.CFA when evaluating DWARF locations for\n// input parameters so that DW_OP_fbreg expressions yield RSP-relative offsets\n// directly — see the comment in setEBPFTracepointOnFunc for the full derivation.\nfunc uprobeEntryPointCFA(t *Target, fn *Function) (uint64, int64, error) {\n\tuprobePC, err := FirstPCAfterPrologue(t, fn, false)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\tbi := t.BinInfo()\n\tfde, err := bi.frameEntries.FDEForPC(uprobePC)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"no FDE for uprobe PC %#x: %w\", uprobePC, err)\n\t}\n\tframectx, err := fde.EstablishFrame(uprobePC)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"cannot establish frame at uprobe PC %#x: %w\", uprobePC, err)\n\t}\n\tif framectx.CFA.Rule != frame.RuleCFA {\n\t\treturn 0, 0, fmt.Errorf(\"unexpected CFA rule %d at uprobe PC %#x\", framectx.CFA.Rule, uprobePC)\n\t}\n\treturn uprobePC, framectx.CFA.Offset, nil\n}\n\n// SetWatchpoint sets a data breakpoint at addr and stores it in the\n// process wide break point table.\nfunc (t *Target) SetWatchpoint(logicalID int, scope *EvalScope, expr string, wtype WatchType, cond ast.Expr) (*Breakpoint, error) {\n\tif (wtype&WatchWrite == 0) && (wtype&WatchRead == 0) {\n\t\treturn nil, errors.New(\"at least one of read and write must be set for watchpoint\")\n\t}\n\n\tn, err := parser.ParseExpr(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\txv, err := scope.evalAST(n)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":695,"sourceCodeEnd":731,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/breakpoints.go#L695-L731","documentation":"The frame context at the uprobe PC uses a CFA rule other than frame.RuleCFA (e.g. an expression-based or register-based rule). Delve's eBPF backend only supports the simple CFA-offset rule, since it must compute the caller stack pointer arithmetically to capture function arguments, so it rejects anything else.","triggerScenarios":"setEBPFTracepointOnFunc on a function whose DWARF CFI describes CFA via an expression or register rule instead of a fixed offset from the stack pointer — typical of optimized/epilogue-dense code or hand-written assembly CFI.","commonSituations":"Tracing functions in binaries built with nonstandard unwind metadata (cgo, asm with .cfi_def_cfa_register/.cfi_def_cfa_expression); uprobe PC placed at an instruction where the CFA rule switches (push-based prologue transitions).","solutions":["Trace a plain Go function whose prologue uses the standard sp-relative CFA rule","Place the uprobe at FirstPCAfterPrologue where the CFA rule is still RuleCFA, instead of fn.Entry","Rebuild the target without hand-written asm in the traced path","Use the regular (stopping) tracepoint backend which does not need CFA computation"],"exampleFix":"// before\nbp, cfa, err := uprobeEntryPointCFA(t, fn.Entry)\n// after\npc, err := FirstPCAfterPrologue(t.ProcessInternal(), fn, true)\nbp, cfa, err := uprobeEntryPointCFA(t, pc)","handlingStrategy":"validation","validationCode":"fde, _ := bi.frameEntries.FDEForPC(pc)\nctx, err := fde.EstablishFrame(pc)\nusable := err == nil && ctx.CFA.Rule == frame.RuleCFA","typeGuard":"func cfaRuleSupported(ctx frame.FrameContext) bool { return ctx.CFA.Rule == frame.RuleCFA }","tryCatchPattern":null,"preventionTips":["Only use --ebpf tracing on standard compiled Go functions","Place uprobes at FirstPCAfterPrologue where CFA is still sp-offset based","Avoid tracing functions in packages containing custom asm prologues","If tracing cgo/asm-heavy code, select the stopping tracepoint backend instead"],"tags":["ebpf","dwarf","unwind","cfa"],"backgroundTag":"unsupported-cfa-rule","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}