diff --git a/src/dwarf.cc b/src/dwarf.cc index 04bca7b..1d1603d 100644 --- a/src/dwarf.cc +++ b/src/dwarf.cc @@ -667,7 +667,7 @@ static void ReadDWARFDebugInfo(dwarf::InfoReader& reader, }); std::string dwo_path = ConstructDwoPath(dwo_info); - if (!dwo_path.empty()) { + if (!dwo_path.empty() && &cu == &cu.skeleton()) { auto file = MmapInputFileFactory().OpenFile(dwo_path); dwarf::File dwo_dwarf; cu.dwarf().open(*file, &dwo_dwarf, sink); diff --git a/tests/dwarf/debug_info/recursive-dwo.test b/tests/dwarf/debug_info/recursive-dwo.test new file mode 100644 index 0000000..3098cc7 --- /dev/null +++ b/tests/dwarf/debug_info/recursive-dwo.test @@ -0,0 +1,121 @@ +# Tests that we handle recursive DWO references gracefully without crashing. +# This reproduces a case where a .dwo file contains a DW_AT_GNU_dwo_name attribute pointing to itself. + +# RUN: mkdir -p %t.dir +# RUN: %yaml2obj %s --docnum=1 -o %t.dir/skeleton.o +# RUN: %yaml2obj %s --docnum=2 -o %t.dir/recursive.dwo + +# Run bloaty from the directory containing the files so relative paths resolve. +# RUN: cd %t.dir && %bloaty -d compileunits skeleton.o | %FileCheck %s + +# If the recursion guard is working, bloaty should read the DWO once, +# resolve the CU name "recursive.c", and stop. It should NOT crash. + +# CHECK: FILE SIZE VM SIZE +# CHECK: -------------- -------------- +# CHECK: [ELF Section Headers] +# CHECK: recursive.c +# CHECK: TOTAL + +# Document 1: skeleton.o +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +ProgramHeaders: + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + FirstSec: .text + LastSec: .text + VAddr: 0x400000 + Align: 0x1000 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x400000 + AddressAlign: 0x10 + Size: 0x100 + - Name: .debug_addr + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: '0000400000000000' +DWARF: + debug_str: + - recursive.dwo + - . + debug_abbrev: + - ID: 0 + Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_GNU_dwo_name + Form: DW_FORM_strp + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_GNU_dwo_id + Form: DW_FORM_data8 + - Attribute: DW_AT_GNU_addr_base + Form: DW_FORM_sec_offset + debug_info: + - Version: 4 + AbbrevTableID: 0 + AbbrOffset: 0x0 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x0 # recursive.dwo + - Value: 0xe # . + - Value: 0xfeedfacefeedface + - Value: 0x0 + +# Document 2: recursive.dwo +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +DWARF: + debug_str: + - recursive.c + - recursive.dwo + - . + debug_abbrev: + - ID: 0 + Table: + - Code: 0x1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_GNU_dwo_id + Form: DW_FORM_data8 + - Attribute: DW_AT_GNU_dwo_name + Form: DW_FORM_strp + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_GNU_addr_index + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + debug_info: + - Version: 4 + AbbrevTableID: 0 + AbbrOffset: 0x0 + AddrSize: 8 + Entries: + - AbbrCode: 0x1 + Values: + - Value: 0x0 # recursive.c + - Value: 0xfeedfacefeedface + - Value: 0xc # recursive.dwo + - Value: 0x1a # . + - Value: 0x0 # low_pc index 0 -> 0x400000 + - Value: 0x100 # high_pc size -> 0x100