go-delve/delve · error

reading debug_info: file reference within a compilation unit

Error message

reading debug_info: file reference within a compilation unit without debug_line section at %#x

What it means

Returned by (*compileUnit).filePath (pkg/proc/bininfo.go:3245) when a DWARF DIE references a file (DW_AT_decl_file or similar) but the compilation unit has no debug_line section loaded (cu.lineInfo == nil). Delve needs the CU's line program file table to resolve a numeric file index to a path; without debug_line the reference cannot be resolved, so this error signals malformed or incomplete DWARF.

Source

Thrown at pkg/proc/bininfo.go:3245

	r := make([]*PackageBuildInfo, 0, len(m))
	for _, pbi := range m {
		r = append(r, pbi)
	}

	sort.Slice(r, func(i, j int) bool { return r[i].ImportPath < r[j].ImportPath })
	return r
}

// cuFilePath takes a compilation unit "cu" and a file index reference
// "fileidx" and returns the corresponding file name entry from the
// DWARF line table associated with the unit; "entry" is the offset of
// the attribute where the file reference originated, for logging
// purposes. Return value is the file string and an error value; error
// will be non-nil if the file could not be recovered, perhaps due to
// malformed DWARF.
func (cu *compileUnit) filePath(fileidx int, entry *dwarf.Entry) (string, error) {
	if cu.lineInfo == nil {
		return "", fmt.Errorf("reading debug_info: file reference within a compilation unit without debug_line section at %#x", entry.Offset)
	}
	// File numbering is slightly different before and after DWARF 5;
	// account for this here. See section 6.2.4 of the DWARF 5 spec.
	if cu.Version < 5 {
		fileidx--
	}
	if fileidx < 0 || fileidx >= len(cu.lineInfo.FileNames) {
		return "", fmt.Errorf("reading debug_info: file index (%d) out of range in compile unit file table at %#x", fileidx, entry.Offset)
	}
	return cu.lineInfo.FileNames[fileidx].Path, nil
}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Rebuild the binary keeping full debug info (do not strip .debug_line; avoid -w and custom section strippers).
  2. Verify the section exists with `readelf -S` / `objdump -h` (look for .debug_line / __debug_line); if missing, fix the build/strip pipeline.
  3. Re-download or re-obtain the binary — a truncated or corrupted file can lose sections.
  4. If produced by a third-party toolchain, check the linker flags (e.g. -Wl,--strip-debug vs full strip) and ensure DWARF is emitted for the offending compile unit.

Example fix

// before: strip removes debug_line too
go build -o app .
strip --strip-debug app   # may drop needed DWARF sections

// after: keep DWARF sections, or strip only symbols
go build -o app .
strip -s app   # or don't strip at all when debugging
Defensive patterns

Strategy: validation

Validate before calling

# Ensure .debug_line exists before debugging/processing the binary:
readelf -S ./app | grep debug_line      # Linux/ELF
objdump -h ./app | grep debug_line      # alternative
echo $?  # non-empty grep means section present

Try / catch

if err != nil && strings.Contains(err.Error(), "without debug_line section") {
    return fmt.Errorf("binary lacks .debug_line; rebuild without stripping: %w", err)
}

Prevention

When it happens

Trigger: Reading DIEs of a compile unit whose debug_line section is missing from the binary or failed to parse, then calling filePath for an entry carrying a file index attribute; typically during function/variable/line-table mapping construction in loadBinaryInfo.

Common situations: Binaries stripped partially (debug_info kept, debug_line removed by custom strip tools), binaries linked from objects produced by non-Go compilers or linkers that drop .debug_line, corrupted download of the binary, DWARF emitted by exotic toolchains (cgo dependencies, Rust/C static libs).

Related errors


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