golang/go · error

no %s symbol found

Error message

no %s symbol found

What it means

In `findPESymbol`, the code iterates through the PE symbol table looking for a symbol by exact name match. If no symbol with the requested name exists in the entire table, this error is returned. This is used internally to find Go runtime symbols like `runtime.pclntab`, `runtime.epclntab`, `runtime.symtab`, and `runtime.esymtab`.

Source

Thrown at src/cmd/internal/objfile/pe.go:166

	textStart = imageBase + uint64(sect.VirtualAddress)
	text, err = sect.Data()
	return
}

func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
	for _, s := range f.Symbols {
		if s.Name != name {
			continue
		}
		if s.SectionNumber <= 0 {
			return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
		}
		if len(f.Sections) < int(s.SectionNumber) {
			return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
		}
		return s, nil
	}
	return nil, fmt.Errorf("no %s symbol found", name)
}

func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
	ssym, err := findPESymbol(f, sname)
	if err != nil {
		return nil, err
	}
	esym, err := findPESymbol(f, ename)
	if err != nil {
		return nil, err
	}
	if ssym.SectionNumber != esym.SectionNumber {
		return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
	}
	sect := f.Sections[ssym.SectionNumber-1]
	data, err := sect.Data()
	if err != nil {
		return nil, err

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Rebuild the binary without symbol stripping: remove `-ldflags=-s` and `-ldflags=-w`.
  2. Confirm the symbol exists: `go tool nm <file> | grep pclntab`.
  3. Ensure the binary was built with Go and not another language if you need Go runtime symbols.
  4. For production binaries where stripping is required, accept that runtime table access will fail in analysis tools.

Example fix

// before — stripped binary lacks runtime symbols
$ go build -ldflags="-s" -o app.exe
f, _ := objfile.Open("app.exe")
// pcln() → findPESymbol("runtime.pclntab") → error: no symbol found

// after — keep symbols for analysis
$ go build -o app.exe
f, _ := objfile.Open("app.exe")
table, err := f.PCLineTable()  // succeeds
Defensive patterns

Strategy: validation

Validate before calling

// Check if required symbols exist in PE before lookup
func hasPESymbol(path, name string) bool {
    f, err := pe.Open(path)
    if err != nil { return false }
    defer f.Close()
    for _, s := range f.Symbols {
        if s.Name == name { return true }
    }
    return false
}

// Usage:
if !hasPESymbol("app.exe", "runtime.pclntab") {
    return fmt.Errorf("binary is stripped — rebuild without -ldflags=-s")
}

Try / catch

sym, err := findPESymbol(pe, "runtime.pclntab")
if err != nil && strings.Contains(err.Error(), "no") && strings.Contains(err.Error(), "symbol found") {
    // Runtime symbols are missing — likely stripped binary
    return fmt.Errorf("%s — rebuild without -ldflags=-s for analysis", err)
}

Prevention

When it happens

Trigger: Calling `findPESymbol` (typically during `loadPETable` or `pcln`) for a symbol name that does not exist in the PE symbol table. Most commonly this happens when looking for `runtime.pclntab` / `runtime.epclntab` in a binary where those symbols were stripped during linking.

Common situations: Analyzing a Windows binary built with `-ldflags=-s` which strips the symbol table. Examining a non-Go PE binary that naturally lacks Go runtime symbols. Using an older Go version where the symbol naming convention differs. The binary was built with a custom linker that omitted these symbols.

Related errors


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