go-delve/delve · error
unsupported location expression for argument %s (uses DW_OP_
Error message
unsupported location expression for argument %s (uses DW_OP_piece)
What it means
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.
Source
Thrown at pkg/proc/fncall.go:697
return argFrameSize, formalArgs, nil
}
func funcCallArgOldABI(fn *Function, bi *BinaryInfo, entry reader.Variable, argname string, typ godwarf.Type, pargFrameSize *int64) (*funcCallArg, error) {
const CFA = 0x1000
var off int64
locprog, _, err := bi.locationExpr(entry, dwarf.AttrLocation, fn.Entry)
if err != nil {
err = fmt.Errorf("could not get argument location of %s: %v", argname, err)
} else {
var pieces []op.Piece
off, pieces, err = op.ExecuteStackProgram(op.DwarfRegisters{CFA: CFA, FrameBase: CFA}, locprog, bi.Arch.PtrSize(), nil)
if err != nil {
err = fmt.Errorf("unsupported location expression for argument %s: %v", argname, err)
}
if pieces != nil {
err = fmt.Errorf("unsupported location expression for argument %s (uses DW_OP_piece)", argname)
}
off -= CFA
}
if err != nil {
// With Go version 1.12 or later we can trust that the arguments appear
// in the same order as declared, which means we can calculate their
// address automatically.
// With this we can call optimized functions (which sometimes do not have
// an argument address, due to a compiler bug) as well as runtime
// functions (which are always optimized).
off = *pargFrameSize
off = alignAddr(off, typ.Align())
}
if e := off + typ.Size(); e > *pargFrameSize {
*pargFrameSize = e
}
View on GitHub (pinned to a23773e6c3)
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
Example fix
// before go build -o app . # optimized: arg location uses DW_OP_piece call f(a) // unsupported location expression for argument a (uses DW_OP_piece) // after go build -gcflags="all=-N -l" -o app . call f(a)
Defensive patterns
Strategy: fallback
Try / catch
if err != nil && strings.Contains(err.Error(), "uses DW_OP_piece") {
// rebuild unoptimized or avoid calling this function
} Prevention
- Rebuild with -gcflags=all="-N -l" so arguments occupy single contiguous slots
- Avoid injecting calls into optimized functions whose args spill across registers/stack
When it happens
Trigger: Old-ABI call injection against a function whose argument DWARF location uses DW_OP_piece (split register/stack representation), typical of optimized code.
Common situations: Optimized builds where an argument spans registers and stack; toolchains that emit piece-based locations for aggregate arguments.
Related errors
- could not find DIE for function %q
- DWARF read error: %v
- could not get argument location of %s: %v
- unsupported location expression for argument %s: %v
- unable to find function context
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/45086421c588e462.
Report an issue: GitHub.