{"record":{"id":"e7402b6d5c7190d0","repo":"go-delve/delve","slug":"can-not-call-optimized-function-s-when-regabi-is","errorCode":null,"errorMessage":"can not call optimized function %s when regabi is in use","messagePattern":"can not call optimized function (.+?) when regabi is in use","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/fncall.go","lineNumber":627,"sourceCode":"\nfunc funcCallArgs(fn *Function, bi *BinaryInfo, includeRet bool) (argFrameSize int64, formalArgs []funcCallArg, err error) {\n\tdwarfTree, err := fn.cu.image.getDwarfTree(fn.offset)\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"DWARF read error: %v\", err)\n\t}\n\n\tif bi.regabi && fn.Optimized() {\n\t\tif runtimeWhitelist[fn.Name] {\n\t\t\truntimeOptimizedWorkaround(bi, fn.cu.image, dwarfTree)\n\t\t} else {\n\t\t\t// Debug info for function arguments on optimized functions is currently\n\t\t\t// too incomplete to attempt injecting calls to arbitrary optimized\n\t\t\t// functions.\n\t\t\t// Prior to regabi we could do this because the ABI was simple enough to\n\t\t\t// manually encode it in Delve.\n\t\t\t// Runtime.mallocgc is an exception, we specifically patch it's DIE to be\n\t\t\t// correct for call injection purposes.\n\t\t\treturn 0, nil, fmt.Errorf(\"can not call optimized function %s when regabi is in use\", fn.Name)\n\t\t}\n\t}\n\n\tvarEntries := reader.Variables(dwarfTree, fn.Entry, int(^uint(0)>>1), reader.VariablesSkipInlinedSubroutines)\n\n\t// typechecks arguments, calculates argument frame size\n\tfor _, entry := range varEntries {\n\t\tif entry.Tag != dwarf.TagFormalParameter {\n\t\t\tcontinue\n\t\t}\n\t\targname, typ, err := readVarEntry(entry.Tree, fn.cu.image)\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\ttyp = godwarf.ResolveTypedef(typ)\n\n\t\tvar formalArg *funcCallArg\n\t\tif bi.regabi {","sourceCodeStart":609,"sourceCodeEnd":645,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/fncall.go#L609-L645","documentation":"With Go's register-based ABI (regabi, Go 1.17+), Delve cannot manually encode calling conventions for optimized functions because the compiler omits complete argument info. Only whitelisted runtime functions (like mallocgc with a patched DIE) are supported, so calling any other optimized function is rejected.","triggerScenarios":"Using 'call' on a function compiled with optimizations (no -N -l) on Go >= 1.17 where bi.regabi is true and the function is not in runtimeWhitelist.","commonSituations":"Debugging production-style builds built without '-gcflags=all=\"-N -l\"' and trying to inject calls into user functions; Go version upgrade to 1.17+ silently changing the ABI.","solutions":["Rebuild with optimizations disabled: go build -gcflags=all=\"-N -l\"","Step past the function and reason about its return value manually instead of calling it","Only call whitelisted runtime functions in optimized builds"],"exampleFix":"// before\ngo build -o app . && dlv exec ./app\ncall compute(x) // can not call optimized function\n// after\ngo build -gcflags=\"all=-N -l\" -o app . && dlv exec ./app\ncall compute(x)","handlingStrategy":"validation","validationCode":"// build unoptimized for call-injection sessions:\n// go build -gcflags=\"all=-N -l\" -o app .","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"optimized function\") {\n    // step over the function and read the return value instead\n}","preventionTips":["Always use -gcflags=all=\"-N -l\" for debug builds on Go 1.17+","Restrict injected calls to non-optimized, non-runtime functions"],"tags":["go","debugger","regabi","optimization","call-injection"],"backgroundTag":"optimized-function-call-unsupported","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}