golang/go · error

subprogram DIE low_pc not convertible to uint64

Error message

subprogram DIE low_pc not convertible to uint64

What it means

Thrown by SubprogLoAndHighPc (dwtest.go:218-223) when DW_AT_low_pc has class ClassAddress but its underlying value cannot be type-asserted to uint64. This is an internal inconsistency: the class promises an address but the value is stored in an incompatible Go type.

Solutions

  1. Inspect lofield.Val's concrete Go type to see what was stored instead of uint64.
  2. If the value is a smaller integer type, widen it explicitly rather than relying on the assertion.
  3. Treat the DIE as malformed and skip; if from the Go toolchain, file a bug with the reproducing binary.
Defensive patterns

Strategy: type-guard

Validate before calling

f := subprogdie.AttrField(dwarf.AttrLowpc)
if f == nil || f.Class != dwarf.ClassAddress { return 0, 0, nil }
lo, ok := f.Val.(uint64)
if !ok { return 0, 0, nil } // inconsistent type/class — skip

Type guard

func lowPCAsUint64(d *dwarf.Entry) (uint64, bool) {
    f := d.AttrField(dwarf.AttrLowpc)
    if f == nil || f.Class != dwarf.ClassAddress {
        return 0, false
    }
    lo, ok := f.Val.(uint64)
    return lo, ok
}

Prevention

When it happens

Trigger: A corrupted or hand-edited DIE where AttrField reports ClassAddress but Val is not uint64; a debug/dwarf decoding edge case for an unusual address size; re-serialized DWARF from a tool that stored the wrong Go type.

Common situations: Binary corruption; third-party DWARF tooling that wrote inconsistent type/class pairs; 32-bit address stored as a narrower int type by a buggy reader.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/ebbb909a0add389e. Report an issue: GitHub.

Appendix: source

Thrown at src/cmd/link/internal/dwtest/dwtest.go:221

// constant, where the high PC could be computed by starting with the
// low PC address and then adding in the high_pc attr offset.  This
// function accepts both styles of specifying a hi/lo pair, returning
// the values or an error if the attributes are malformed in some way.
func SubprogLoAndHighPc(subprogdie *dwarf.Entry) (lo uint64, hi uint64, err error) {
	// The low_pc attr for a subprogram DIE has to be of class address.
	lofield := subprogdie.AttrField(dwarf.AttrLowpc)
	if lofield == nil {
		err = fmt.Errorf("subprogram DIE has no low_pc attr")
		return
	}
	if lofield.Class != dwarf.ClassAddress {
		err = fmt.Errorf("subprogram DIE low_pc attr is not of class address")
		return
	}
	if lopc, ok := lofield.Val.(uint64); ok {
		lo = lopc
	} else {
		err = fmt.Errorf("subprogram DIE low_pc not convertible to uint64")
		return
	}

	// For the high_pc value, we'll accept either an address or a constant
	// offset from lo pc.
	hifield := subprogdie.AttrField(dwarf.AttrHighpc)
	if hifield == nil {
		err = fmt.Errorf("subprogram DIE has no high_pc attr")
		return
	}
	switch hifield.Class {
	case dwarf.ClassAddress:
		if hipc, ok := hifield.Val.(uint64); ok {
			hi = hipc
		} else {
			err = fmt.Errorf("subprogram DIE high not convertible to uint64")
			return
		}

View on GitHub (pinned to b6b368adc5)