From 2ecf928153fc56dcb6bb0bd910584eac86bc23bd Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Sat, 27 Mar 2021 21:21:14 +0100 Subject: [PATCH] [lldb/DWARF] Fix a crash parsing invalid dwarf (pr49678) If the debug info is missing the terminating null die, we would crash when trying to access the nonexisting children/siblings. This was discovered because the test case for D98619 accidentaly produced such input. --- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 5 +++ .../SymbolFile/DWARF/DWARFUnitTest.cpp | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 86b18615da7d..ea10ba75afa8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -236,6 +236,11 @@ void DWARFUnit::ExtractDIEsRWLocked() { } if (!m_die_array.empty()) { + // The last die cannot have children (if it did, it wouldn't be the last one). + // This only makes a difference for malformed dwarf that does not have a + // terminating null die. + m_die_array.back().SetHasChildren(false); + if (m_first_die) { // Only needed for the assertion. m_first_die.SetHasChildren(m_die_array.front().HasChildren()); diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp index 3a4b1cfd8ba7..f5cfd1e61120 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp @@ -47,3 +47,40 @@ DWARF: ASSERT_NE(die_first, nullptr); EXPECT_TRUE(die_first->IsNULL()); } + +TEST(DWARFUnitTest, MissingSentinel) { + // Make sure we don't crash if the debug info is missing a null DIE sentinel. + const char *yamldata = R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 +DWARF: + debug_abbrev: + - Table: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_language + Form: DW_FORM_data2 + debug_info: + - Version: 4 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x000000000000000C +)"; + + YAMLModuleTester t(yamldata); + ASSERT_TRUE((bool)t.GetDwarfUnit()); + + DWARFUnit *unit = t.GetDwarfUnit(); + const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE(); + ASSERT_NE(die_first, nullptr); + EXPECT_EQ(die_first->GetFirstChild(), nullptr); + EXPECT_EQ(die_first->GetSibling(), nullptr); +}