{"record":{"id":"ffbdac179c848374","repo":"golang/go","slug":"cmd-unrecognized-mangling-scheme","errorCode":null,"errorMessage":"cmd: unrecognized mangling scheme","messagePattern":"cmd: unrecognized mangling scheme","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/pkgpath/pkgpath.go","lineNumber":62,"sourceCode":"\t}\n\n\tcommand := exec.Command(cmd, \"-S\", \"-o\", \"-\", gofilename)\n\tbuf, err := command.Output()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Original mangling: go.l__ufer.Run\n\t// Mangling v2: go.l..u00e4ufer.Run\n\t// Mangling v3: go_0l_u00e4ufer.Run\n\tif bytes.Contains(buf, []byte(\"go_0l_u00e4ufer.Run\")) {\n\t\treturn toSymbolV3, nil\n\t} else if bytes.Contains(buf, []byte(\"go.l..u00e4ufer.Run\")) {\n\t\treturn toSymbolV2, nil\n\t} else if bytes.Contains(buf, []byte(\"go.l__ufer.Run\")) {\n\t\treturn toSymbolV1, nil\n\t} else {\n\t\treturn nil, errors.New(cmd + \": unrecognized mangling scheme\")\n\t}\n}\n\n// mangleCheckCode is the package we compile to determine the mangling scheme.\nconst mangleCheckCode = `\npackage läufer\nfunc Run(x int) int {\n  return 1\n}\n`\n\n// toSymbolV1 converts a package path using the original mangling scheme.\nfunc toSymbolV1(ppath string) string {\n\tclean := func(r rune) rune {\n\t\tswitch {\n\t\tcase 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',\n\t\t\t'0' <= r && r <= '9':\n\t\t\treturn r","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/pkgpath/pkgpath.go#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nfn, err := pkgpath.ToSymbolFunc(\"gccgo\", tmpdir)\n// err == \"gccgo: unrecognized mangling scheme\"\n\n// after: verify the probe assembly manually first\nout, _ := exec.Command(\"gccgo\", \"-S\", \"-o\", \"-\", probeFile).Output()\nfmt.Printf(\"%s\\n\", out) // inspect which mangling the compiler emits\n// then either pick a compatible gccgo or add a new scheme branch","handlingStrategy":"validation","validationCode":"// Verify the compiler emits a known mangling before relying on ToSymbolFunc.\nfunc detectMangling(cmd string) (string, error) {\n    f, _ := os.CreateTemp(\"\", \"probe*.go\")\n    defer os.Remove(f.Name())\n    f.WriteString(\"package läufer\\nfunc Run(x int) int { return 1 }\\n\")\n    f.Close()\n    out, err := exec.Command(cmd, \"-S\", \"-o\", \"-\", f.Name()).Output()\n    if err != nil { return \"\", err }\n    for _, m := range []string{\"go_0l_u00e4ufer.Run\", \"go.l..u00e4ufer.Run\", \"go.l__ufer.Run\"} {\n        if bytes.Contains(out, []byte(m)) { return m, nil }\n    }\n    return \"\", errors.New(\"no known mangling in assembly\")\n}","typeGuard":"func isUnrecognizedMangling(err error) bool {\n    return err != nil && strings.HasSuffix(err.Error(), \"unrecognized mangling scheme\")\n}","tryCatchPattern":"fn, err := pkgpath.ToSymbolFunc(cc, tmpdir)\nif err != nil && strings.HasSuffix(err.Error(), \"unrecognized mangling scheme\") {\n    return fmt.Errorf(\"compiler %s uses an unsupported symbol mangling; use a supported gccgo/GoLLVM version\", cc)\n}","preventionTips":["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."],"tags":["gccgo","pkgpath","symbol-mangling","gollvm","go-toolchain"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}