go-delve/delve · error

DWARF read error: %v

Error message

DWARF read error: %v

What it means

funcCallArgs needs the function's DWARF DIE tree to enumerate formal arguments and compute the argument frame size. If getDwarfTree(fn.offset) fails to read or parse the DIE, the underlying DWARF error is wrapped as 'DWARF read error'.

Source

Thrown at pkg/proc/fncall.go:613

		var err error
		formalArgVar, err = extractVarInfoFromEntry(scope.target, formalScope.BinInfo, formalScope.image(), formalScope.Regs, formalScope.Mem, formalArg.dwarfEntry, 0)
		if err != nil {
			return err
		}
	} else {
		formalArgVar = newVariable(formalArg.name, uint64(formalArg.off+formalScope.Regs.CFA), formalArg.typ, scope.BinInfo, scope.Mem)
	}
	if err := scope.setValue(formalArgVar, actualArg, actualArg.Name); err != nil {
		return err
	}

	return nil
}

func funcCallArgs(fn *Function, bi *BinaryInfo, includeRet bool) (argFrameSize int64, formalArgs []funcCallArg, err error) {
	dwarfTree, err := fn.cu.image.getDwarfTree(fn.offset)
	if err != nil {
		return 0, nil, fmt.Errorf("DWARF read error: %v", err)
	}

	if bi.regabi && fn.Optimized() {
		if runtimeWhitelist[fn.Name] {
			runtimeOptimizedWorkaround(bi, fn.cu.image, dwarfTree)
		} else {
			// Debug info for function arguments on optimized functions is currently
			// too incomplete to attempt injecting calls to arbitrary optimized
			// functions.
			// Prior to regabi we could do this because the ABI was simple enough to
			// manually encode it in Delve.
			// Runtime.mallocgc is an exception, we specifically patch it's DIE to be
			// correct for call injection purposes.
			return 0, nil, fmt.Errorf("can not call optimized function %s when regabi is in use", fn.Name)
		}
	}

	varEntries := reader.Variables(dwarfTree, fn.Entry, int(^uint(0)>>1), reader.VariablesSkipInlinedSubroutines)

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Rebuild the binary keeping DWARF sections (do not strip; use -gcflags=all="-N -l" for debugging)
  2. Verify .debug_info is present (readelf -S / objdump -h)
  3. Reload the correct unstripped binary in the debug session

Example fix

// before
strip ./app && dlv exec ./app
call app.Foo() // DWARF read error
// after
dlv exec ./app  # keep unstripped binary
call app.Foo()
Defensive patterns

Strategy: fallback

Validate before calling

// check the binary keeps DWARF
// readelf -S ./app | grep debug_info

Try / catch

if err != nil && strings.Contains(err.Error(), "DWARF read error") {
    // fall back to manual inspection (breakpoints, print) instead of calling
}

Prevention

When it happens

Trigger: Injecting a call to a function whose compile unit's DWARF data is missing, truncated, or unreadable at fn.offset — e.g. stripped binary sections, malformed DWARF, or a partially loaded image.

Common situations: Binaries stripped after linking (strip/objcopy), split/incremental builds with corrupted debug info, or reading a core/executable whose .debug_info section was removed.

Related errors


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