{"record":{"id":"45086421c588e462","repo":"go-delve/delve","slug":"unsupported-location-expression-for-argument-s-u","errorCode":null,"errorMessage":"unsupported location expression for argument %s (uses DW_OP_piece)","messagePattern":"unsupported location expression for argument (.+?) \\(uses DW_OP_piece\\)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/fncall.go","lineNumber":697,"sourceCode":"\n\treturn argFrameSize, formalArgs, nil\n}\n\nfunc funcCallArgOldABI(fn *Function, bi *BinaryInfo, entry reader.Variable, argname string, typ godwarf.Type, pargFrameSize *int64) (*funcCallArg, error) {\n\tconst CFA = 0x1000\n\tvar off int64\n\n\tlocprog, _, err := bi.locationExpr(entry, dwarf.AttrLocation, fn.Entry)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"could not get argument location of %s: %v\", argname, err)\n\t} else {\n\t\tvar pieces []op.Piece\n\t\toff, pieces, err = op.ExecuteStackProgram(op.DwarfRegisters{CFA: CFA, FrameBase: CFA}, locprog, bi.Arch.PtrSize(), nil)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"unsupported location expression for argument %s: %v\", argname, err)\n\t\t}\n\t\tif pieces != nil {\n\t\t\terr = fmt.Errorf(\"unsupported location expression for argument %s (uses DW_OP_piece)\", argname)\n\t\t}\n\t\toff -= CFA\n\t}\n\tif err != nil {\n\t\t// With Go version 1.12 or later we can trust that the arguments appear\n\t\t// in the same order as declared, which means we can calculate their\n\t\t// address automatically.\n\t\t// With this we can call optimized functions (which sometimes do not have\n\t\t// an argument address, due to a compiler bug) as well as runtime\n\t\t// functions (which are always optimized).\n\t\toff = *pargFrameSize\n\t\toff = alignAddr(off, typ.Align())\n\t}\n\n\tif e := off + typ.Size(); e > *pargFrameSize {\n\t\t*pargFrameSize = e\n\t}\n","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/fncall.go#L679-L715","documentation":"If the argument's location expression evaluates successfully but yields multiple DW_OP_piece results, the argument is stored in several locations (registers/pieces), which Delve's old-ABI argument marshalling cannot handle — it needs a single contiguous stack slot.","triggerScenarios":"Old-ABI call injection against a function whose argument DWARF location uses DW_OP_piece (split register/stack representation), typical of optimized code.","commonSituations":"Optimized builds where an argument spans registers and stack; toolchains that emit piece-based locations for aggregate arguments.","solutions":["Rebuild with -gcflags=all=\"-N -l\" so each argument has a single contiguous location","Upgrade Delve/Go so arguments use the regabi path instead of the old ABI","Skip call injection for this function"],"exampleFix":"// before\ngo build -o app .  # optimized: arg location uses DW_OP_piece\ncall f(a) // unsupported location expression for argument a (uses DW_OP_piece)\n// after\ngo build -gcflags=\"all=-N -l\" -o app .\ncall f(a)","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"uses DW_OP_piece\") {\n    // rebuild unoptimized or avoid calling this function\n}","preventionTips":["Rebuild with -gcflags=all=\"-N -l\" so arguments occupy single contiguous slots","Avoid injecting calls into optimized functions whose args spill across registers/stack"],"tags":["go","debugger","dwarf","dwop-piece","call-injection"],"backgroundTag":"unsupported-location-expression","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}