{"record":{"id":"ebbb909a0add389e","repo":"golang/go","slug":"subprogram-die-low-pc-not-convertible-to-uint64","errorCode":null,"errorMessage":"subprogram DIE low_pc not convertible to uint64","messagePattern":"subprogram DIE low_pc not convertible to uint64","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/link/internal/dwtest/dwtest.go","lineNumber":221,"sourceCode":"// constant, where the high PC could be computed by starting with the\n// low PC address and then adding in the high_pc attr offset.  This\n// function accepts both styles of specifying a hi/lo pair, returning\n// the values or an error if the attributes are malformed in some way.\nfunc SubprogLoAndHighPc(subprogdie *dwarf.Entry) (lo uint64, hi uint64, err error) {\n\t// The low_pc attr for a subprogram DIE has to be of class address.\n\tlofield := subprogdie.AttrField(dwarf.AttrLowpc)\n\tif lofield == nil {\n\t\terr = fmt.Errorf(\"subprogram DIE has no low_pc attr\")\n\t\treturn\n\t}\n\tif lofield.Class != dwarf.ClassAddress {\n\t\terr = fmt.Errorf(\"subprogram DIE low_pc attr is not of class address\")\n\t\treturn\n\t}\n\tif lopc, ok := lofield.Val.(uint64); ok {\n\t\tlo = lopc\n\t} else {\n\t\terr = fmt.Errorf(\"subprogram DIE low_pc not convertible to uint64\")\n\t\treturn\n\t}\n\n\t// For the high_pc value, we'll accept either an address or a constant\n\t// offset from lo pc.\n\thifield := subprogdie.AttrField(dwarf.AttrHighpc)\n\tif hifield == nil {\n\t\terr = fmt.Errorf(\"subprogram DIE has no high_pc attr\")\n\t\treturn\n\t}\n\tswitch hifield.Class {\n\tcase dwarf.ClassAddress:\n\t\tif hipc, ok := hifield.Val.(uint64); ok {\n\t\t\thi = hipc\n\t\t} else {\n\t\t\terr = fmt.Errorf(\"subprogram DIE high not convertible to uint64\")\n\t\t\treturn\n\t\t}","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/link/internal/dwtest/dwtest.go#L203-L239","documentation":"Thrown by SubprogLoAndHighPc (dwtest.go:218-223) when DW_AT_low_pc has class ClassAddress but its underlying value cannot be type-asserted to uint64. This is an internal inconsistency: the class promises an address but the value is stored in an incompatible Go type.","triggerScenarios":"A corrupted or hand-edited DIE where AttrField reports ClassAddress but Val is not uint64; a debug/dwarf decoding edge case for an unusual address size; re-serialized DWARF from a tool that stored the wrong Go type.","commonSituations":"Binary corruption; third-party DWARF tooling that wrote inconsistent type/class pairs; 32-bit address stored as a narrower int type by a buggy reader.","solutions":["Inspect lofield.Val's concrete Go type to see what was stored instead of uint64.","If the value is a smaller integer type, widen it explicitly rather than relying on the assertion.","Treat the DIE as malformed and skip; if from the Go toolchain, file a bug with the reproducing binary."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"f := subprogdie.AttrField(dwarf.AttrLowpc)\nif f == nil || f.Class != dwarf.ClassAddress { return 0, 0, nil }\nlo, ok := f.Val.(uint64)\nif !ok { return 0, 0, nil } // inconsistent type/class — skip","typeGuard":"func lowPCAsUint64(d *dwarf.Entry) (uint64, bool) {\n    f := d.AttrField(dwarf.AttrLowpc)\n    if f == nil || f.Class != dwarf.ClassAddress {\n        return 0, false\n    }\n    lo, ok := f.Val.(uint64)\n    return lo, ok\n}","tryCatchPattern":null,"preventionTips":["Type-assert the value to uint64 explicitly before use.","A ClassAddress attribute whose value is not uint64 indicates corruption — skip the DIE."],"tags":["dwarf","go-linker","dwtest","debug-info"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}