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

  1. Rebuild with -gcflags=all="-N -l" so each argument has a single contiguous location
  2. Upgrade Delve/Go so arguments use the regabi path instead of the old ABI
  3. 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

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


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/45086421c588e462. Report an issue: GitHub.