go-delve/delve · error

could not read section .gopclntab

Error message

could not read section .gopclntab

What it means

readPcLnTableElf cannot locate the Go pclntab section (.gopclntab) in an ELF binary, nor its PIE-relocated variant (.data.rel.ro.gopclntab). Delve needs this table for Go-runtime function metadata when DWARF-based lookup falls back to runtime tables.

Source

Thrown at pkg/proc/pclntab.go:22

	"debug/elf"
	"debug/macho"
	"errors"
	"fmt"

	"github.com/go-delve/delve/pkg/internal/gosym"
)

func readPcLnTableElf(exe *elf.File, path string) (*gosym.Table, uint64, error) {
	// Default section label is .gopclntab
	sectionLabel := ".gopclntab"

	section := exe.Section(sectionLabel)
	if section == nil {
		// binary may be built with -pie
		sectionLabel = ".data.rel.ro.gopclntab"
		section = exe.Section(sectionLabel)
		if section == nil {
			return nil, 0, errors.New("could not read section .gopclntab")
		}
	}
	tableData, err := section.Data()
	if err != nil {
		return nil, 0, errors.New("found section but could not read .gopclntab")
	}

	addr := exe.Section(".text").Addr
	lineTable := gosym.NewLineTable(tableData, addr)
	symTable, err := gosym.NewTable([]byte{}, lineTable)
	if err != nil {
		return nil, 0, fmt.Errorf("could not create symbol table from  %s ", path)
	}
	return symTable, section.Addr, nil
}

func readPcLnTableMacho(exe *macho.File, path string) (*gosym.Table, uint64, error) {
	// Default section label is __gopclntab

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Verify the binary was produced by the Go toolchain (go version -m <binary>)
  2. Do not strip Go binaries with external strippers; keep .gopclntab intact
  3. Rebuild with a supported Go version and without -ldflags that remove runtime sections
  4. Confirm the binary architecture/format matches what delve was asked to open

Example fix

// before
go build -ldflags="-s -w" -o app . && strip app
// after
go build -o app . // keep pclntab and symbol metadata
Defensive patterns

Strategy: validation

Validate before calling

out, _ := exec.Command("go", "version", "-m", binaryPath).Output()
if !strings.Contains(string(out), "go") {
    return fmt.Errorf("%s is not a Go binary", binaryPath)
}

Try / catch

_, _, err := loadBinaryInfo(path)
if err != nil && strings.Contains(err.Error(), "could not read section .gopclntab") {
    return fmt.Errorf("not a Go-built ELF binary (or pclntab stripped): %w", err)
}

Prevention

When it happens

Trigger: Loading (attach/exec/core) an ELF binary whose symbolization falls back to loadBinaryInfoGoRuntimeElf but that contains neither .gopclntab nor .data.rel.ro.gopclntab — typically a non-Go binary, a stripped Go binary, or one built/linked with an unusual toolchain.

Common situations: Attaching delve to a C/C++ program that happens to be loaded in a mixed-process scenario; analyzing a Go binary stripped with objcopy that removed the section; very old Go versions or cgo-heavy builds with different section layout.

Related errors


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