{"record":{"id":"cfb25b3fd31ddb47","repo":"golang/go","slug":"subprogram-die-low-pc-attr-is-not-of-class-address","errorCode":null,"errorMessage":"subprogram DIE low_pc attr is not of class address","messagePattern":"subprogram DIE low_pc attr is not of class address","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/link/internal/dwtest/dwtest.go","lineNumber":215,"sourceCode":"}\n\n// SubprogLoAndHighPc returns the values of the lo_pc and high_pc\n// attrs of the DWARF DIE subprogdie.  For DWARF versions 2-3, both of\n// these attributes had to be of class address; with DWARF 4 the rules\n// were changed, allowing compilers to emit a high PC attr of class\n// 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:","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/link/internal/dwtest/dwtest.go#L197-L233","documentation":"Thrown by SubprogLoAndHighPc (dwtest.go:214-217) when the DW_AT_low_pc attribute exists but its class is not ClassAddress. Per DWARF, low_pc must be an address-class attribute; any other class indicates a producer bug or a misread DIE.","triggerScenarios":"A subprogram DIE whose low_pc was encoded as a constant, block, or reference instead of an address; reading DWARF produced by a non-conforming compiler; re-encoding artifact from the linker.","commonSituations":"Compiler/linker emits a non-address low_pc (invalid DWARF); binary corruption; reading a DIE intended for a different DWARF consumer.","solutions":["Inspect lofield.Class and lofield.Val to understand what class was emitted instead of ClassAddress.","Treat the DIE as malformed and skip it if it cannot be reconciled with the DWARF spec.","Report a linker/compiler bug if the binary comes from the Go toolchain and the attribute class is wrong."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"f := subprogdie.AttrField(dwarf.AttrLowpc)\nif f == nil || f.Class != dwarf.ClassAddress {\n    // not an address-class low_pc — skip or report malformed DIE\n    return 0, 0, nil\n}","typeGuard":"func isAddressLowPC(d *dwarf.Entry) bool {\n    f := d.AttrField(dwarf.AttrLowpc)\n    return f != nil && f.Class == dwarf.ClassAddress\n}","tryCatchPattern":null,"preventionTips":["Verify AttrField class equals ClassAddress before relying on low_pc.","Non-conforming DWARF should be skipped, not silently coerced."],"tags":["dwarf","go-linker","dwtest","debug-info"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}