golang/go · error
cmd: unrecognized mangling scheme
Error message
cmd: unrecognized mangling scheme
What it means
Thrown by pkgpath.ToSymbolFunc after it compiles a probe package ('läufer.Run') with the given gccgo/GoLLVM compiler and scans the assembly output for one of three known mangled symbol spellings (v1 go.l__ufer.Run, v2 go.l..u00e4ufer.Run, v3 go_0l_u00e4ufer.Run). If none of the expected manglings appear, the toolchain cannot determine which symbol-mangling scheme to use and refuses to proceed. This package is used only by gccgo/GoLLVM-based builds, not by gc.
Source
Thrown at src/cmd/internal/pkgpath/pkgpath.go:62
}
command := exec.Command(cmd, "-S", "-o", "-", gofilename)
buf, err := command.Output()
if err != nil {
return nil, err
}
// Original mangling: go.l__ufer.Run
// Mangling v2: go.l..u00e4ufer.Run
// Mangling v3: go_0l_u00e4ufer.Run
if bytes.Contains(buf, []byte("go_0l_u00e4ufer.Run")) {
return toSymbolV3, nil
} else if bytes.Contains(buf, []byte("go.l..u00e4ufer.Run")) {
return toSymbolV2, nil
} else if bytes.Contains(buf, []byte("go.l__ufer.Run")) {
return toSymbolV1, nil
} else {
return nil, errors.New(cmd + ": unrecognized mangling scheme")
}
}
// mangleCheckCode is the package we compile to determine the mangling scheme.
const mangleCheckCode = `
package läufer
func Run(x int) int {
return 1
}
`
// toSymbolV1 converts a package path using the original mangling scheme.
func toSymbolV1(ppath string) string {
clean := func(r rune) rune {
switch {
case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
'0' <= r && r <= '9':
return rView on GitHub (pinned to b6b368adc5)
Solutions
- Confirm the gccgo/GoLLVM compiler actually works: run `cmd -S -o - probe.go` manually and inspect the assembly for the läufer.Run symbol.
- Use a gccgo/GoLLVM version whose mangling is one of the three supported schemes.
- Extend pkgpath with a fourth mangling detector if you control the fork (add another bytes.Contains branch mapping to a new toSymbolVN).
- Check that tmpdir is writable and the probe .go file was created and compiled (an earlier os/exec error would have returned already, but a silently empty stdout triggers this).
Example fix
// before
fn, err := pkgpath.ToSymbolFunc("gccgo", tmpdir)
// err == "gccgo: unrecognized mangling scheme"
// after: verify the probe assembly manually first
out, _ := exec.Command("gccgo", "-S", "-o", "-", probeFile).Output()
fmt.Printf("%s\n", out) // inspect which mangling the compiler emits
// then either pick a compatible gccgo or add a new scheme branch Defensive patterns
Strategy: validation
Validate before calling
// Verify the compiler emits a known mangling before relying on ToSymbolFunc.
func detectMangling(cmd string) (string, error) {
f, _ := os.CreateTemp("", "probe*.go")
defer os.Remove(f.Name())
f.WriteString("package läufer\nfunc Run(x int) int { return 1 }\n")
f.Close()
out, err := exec.Command(cmd, "-S", "-o", "-", f.Name()).Output()
if err != nil { return "", err }
for _, m := range []string{"go_0l_u00e4ufer.Run", "go.l..u00e4ufer.Run", "go.l__ufer.Run"} {
if bytes.Contains(out, []byte(m)) { return m, nil }
}
return "", errors.New("no known mangling in assembly")
} Type guard
func isUnrecognizedMangling(err error) bool {
return err != nil && strings.HasSuffix(err.Error(), "unrecognized mangling scheme")
} Try / catch
fn, err := pkgpath.ToSymbolFunc(cc, tmpdir)
if err != nil && strings.HasSuffix(err.Error(), "unrecognized mangling scheme") {
return fmt.Errorf("compiler %s uses an unsupported symbol mangling; use a supported gccgo/GoLLVM version", cc)
} Prevention
- Probe the compiler assembly once at build setup and fail with an actionable message.
- Pin a supported gccgo/GoLLVM version in CI.
- Inspect probe assembly when upgrading the compiler.
When it happens
Trigger: Calling pkgpath.ToSymbolFunc(cmd, tmpdir) where cmd is a gccgo/GoLLVM compiler whose assembly output does not contain any of the three recognized mangled forms — e.g. an unknown fork, a newer version with a fourth mangling, a compiler that emits different probe output, or where the probe compile produced empty/unexpected assembly.
Common situations: Upgrading or forking gccgo/GoLLVM such that its name mangling diverges from the three known schemes. A broken gccgo install (assembly output empty because the compile itself failed but produced no error on stdout). A compiler that strips or obfuscates the probe symbols.
Related errors
- importcfg:%d: invalid packagefile: syntax is "packagefile pa
- importcfg:%d: invalid importmap: syntax is "importmap old=ne
- gccgo -importcfg does not support shared libraries
- non-file URL
- file URL missing path
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/ffbdac179c848374.
Report an issue: GitHub.