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 r

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Confirm the gccgo/GoLLVM compiler actually works: run `cmd -S -o - probe.go` manually and inspect the assembly for the läufer.Run symbol.
  2. Use a gccgo/GoLLVM version whose mangling is one of the three supported schemes.
  3. Extend pkgpath with a fourth mangling detector if you control the fork (add another bytes.Contains branch mapping to a new toSymbolVN).
  4. 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

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


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