{"record":{"id":"2bf0d9694abcc5d9","repo":"golang/go","slug":"pcln-not-available-in-go-object-file","errorCode":null,"errorMessage":"pcln not available in go object file","messagePattern":"pcln not available in go object file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/objfile/goobj.go","lineNumber":227,"sourceCode":"\tn := ndef + uint32(r.NNonpkgref())\n\tfor i := ndef; i < n; i++ {\n\t\tosym := r.Sym(i)\n\t\tsym := Sym{Name: osym.Name(r), Code: 'U'}\n\t\tsyms = append(syms, sym)\n\t}\n\tfor i := 0; i < nrefName; i++ {\n\t\trn := r.RefName(i)\n\t\tsym := Sym{Name: rn.Name(r), Code: 'U'}\n\t\tsyms = append(syms, sym)\n\t}\n\n\treturn syms, nil\n}\n\nfunc (f *goobjFile) pcln() (textStart uint64, pclntab []byte, err error) {\n\t// Should never be called. We implement Liner below, callers\n\t// should use that instead.\n\treturn 0, nil, fmt.Errorf(\"pcln not available in go object file\")\n}\n\n// PCToLine returns the file name, line, and function data for the given pc.\n// Returns \"\",0,nil if unknown.\n// This function implements the Liner interface in preference to pcln() above.\nfunc (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {\n\tr := f.r\n\tif f.arch == nil {\n\t\treturn \"\", 0, nil\n\t}\n\tgetSymData := func(s goobj.SymRef) []byte {\n\t\tif s.PkgIdx != goobj.PkgIdxHashed {\n\t\t\t// We don't need the data for non-hashed symbols, yet.\n\t\t\tpanic(\"not supported\")\n\t\t}\n\t\ti := s.SymIdx + uint32(r.NSym()+r.NHashed64def())\n\t\treturn r.BytesAt(r.DataOff(i), r.DataSize(i))\n\t}","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/objfile/goobj.go#L209-L245","documentation":"Go object files (`.o` files produced by the compiler, not linked executables) store line-table data in a format that is read through the `Liner` interface (`PCToLine`, `LineToPC`), not through the `pcln()` method. This stub is implemented solely to satisfy the `rawFile` interface contract and should never be reached by callers. If it is, it indicates a bug in the calling code.","triggerScenarios":"A code path in `objfile` that calls `pcln()` on a `goobjFile` instead of routing through the `Liner` interface. This is an internal invariant violation, not a user-facing configuration problem.","commonSituations":"Modifying the `objfile` package without respecting the `Liner` interface convention. A regression in the toolchain's internal binary analysis code. Using a forked or patched Go toolchain that broke the caller routing logic.","solutions":["Ensure callers use `File.PCLineTable()` (which returns a `Liner`) instead of directly calling `pcln()` on a `goobjFile`.","If you are modifying `objfile`, check that `goobjFile` implements `Liner` via `PCToLine` and `LineToPC`.","Report this as a Go bug if encountered with an unmodified toolchain."],"exampleFix":"// before — wrong code path reaches pcln()\nliner, _ := f.PCLineTable()  // on .o files, this should return Liner\n// If internal code mistakenly calls pcln() on goobjFile, fix the dispatch:\n\n// after — use Liner interface\nliner, err := f.PCLineTable()\nfile, line, fn := liner.PCToLine(pc)  // correct path for .o files","handlingStrategy":"validation","validationCode":"// Use PCLineTable() which returns Liner, never pcln() directly\nfunc safeGetLiner(f *objfile.File) (objfile.Liner, error) {\n    return f.PCLineTable()  // routes correctly for all file types\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use File.PCLineTable() which returns the Liner interface — it dispatches correctly for .o files.","Never call pcln() directly on a rawFile implementation.","If modifying objfile, test with both .o files and linked executables."],"tags":["goobj","pclntab","internal-invariant","objfile"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}