[llvm] b7459a1 - [DWARF] Fix crash for DWARFDie::dump.

Rafael Auler via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 14 18:47:02 PDT 2021


Author: Alexander Yermolovich
Date: 2021-04-14T18:46:34-07:00
New Revision: b7459a10dad1cf71dc0e6dcb97256bfbe3c2a28d

URL: https://github.com/llvm/llvm-project/commit/b7459a10dad1cf71dc0e6dcb97256bfbe3c2a28d
DIFF: https://github.com/llvm/llvm-project/commit/b7459a10dad1cf71dc0e6dcb97256bfbe3c2a28d.diff

LOG: [DWARF] Fix crash for DWARFDie::dump.

When DIE is extracted manually, the DieArray is empty. When dump is invoked on aforementioned DIE it tries to extract child, even if Dump options say otherwise. Resulting in crash.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D99698

Added: 
    llvm/unittests/DebugInfo/DWARF/DWARFDieManualExtractTest.cpp

Modified: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
    llvm/unittests/DebugInfo/DWARF/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index d5daa3c32b1f7..a0095acd9e357 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -251,9 +251,6 @@ class DWARFUnit {
 protected:
   const DWARFUnitHeader &getHeader() const { return Header; }
 
-  /// Size in bytes of the parsed unit header.
-  uint32_t getHeaderSize() const { return Header.getSize(); }
-
   /// Find the unit's contribution to the string offsets table and determine its
   /// length and form. The given offset is expected to be derived from the unit
   /// DIE's DW_AT_str_offsets_base attribute.
@@ -290,6 +287,8 @@ class DWARFUnit {
   uint8_t getDwarfOffsetByteSize() const {
     return Header.getDwarfOffsetByteSize();
   }
+  /// Size in bytes of the parsed unit header.
+  uint32_t getHeaderSize() const { return Header.getSize(); }
   uint64_t getLength() const { return Header.getLength(); }
   dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
   uint8_t getUnitType() const { return Header.getUnitType(); }

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 5a55f3a041484..79438dcf843ae 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -635,14 +635,14 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
         for (const DWARFAttribute &AttrValue : attributes())
           dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts);
 
-        DWARFDie child = getFirstChild();
-        if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
+        if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0) {
+          DWARFDie Child = getFirstChild();
           DumpOpts.ChildRecurseDepth--;
           DIDumpOptions ChildDumpOpts = DumpOpts;
           ChildDumpOpts.ShowParents = false;
-          while (child) {
-            child.dump(OS, Indent + 2, ChildDumpOpts);
-            child = child.getSibling();
+          while (Child) {
+            Child.dump(OS, Indent + 2, ChildDumpOpts);
+            Child = Child.getSibling();
           }
         }
       } else {

diff  --git a/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt b/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
index 90a6bd7ef62e1..29cdec9064f0b 100644
--- a/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/unittests/DebugInfo/DWARF/CMakeLists.txt
@@ -19,6 +19,7 @@ add_llvm_unittest(DebugInfoDWARFTests
   DWARFDebugInfoTest.cpp
   DWARFDebugLineTest.cpp
   DWARFDieTest.cpp
+  DWARFDieManualExtractTest.cpp
   DWARFExpressionCompactPrinterTest.cpp
   DWARFFormValueTest.cpp
   DWARFListTableTest.cpp

diff  --git a/llvm/unittests/DebugInfo/DWARF/DWARFDieManualExtractTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDieManualExtractTest.cpp
new file mode 100644
index 0000000000000..458f1db63c5c2
--- /dev/null
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDieManualExtractTest.cpp
@@ -0,0 +1,81 @@
+//===-llvm/unittest/DebugInfo/DWARFDieManualExtractTest.cpp---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfGenerator.h"
+#include "DwarfUtils.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/ObjectYAML/DWARFEmitter.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::dwarf;
+using namespace utils;
+
+namespace {
+
+TEST(DWARFDie, manualExtractDump) {
+  typedef uint32_t AddrType;
+  uint16_t Version = 4;
+  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
+  if (!isObjectEmissionSupported(Triple))
+    return;
+
+  auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
+  ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
+  dwarfgen::Generator *DG = ExpectedDG.get().get();
+  dwarfgen::CompileUnit &DGCU = DG->addCompileUnit();
+  dwarfgen::DIE CUDie = DGCU.getUnitDIE();
+
+  CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c");
+  CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C);
+
+  dwarfgen::DIE SubprogramDie = CUDie.addChild(DW_TAG_subprogram);
+  SubprogramDie.addAttribute(DW_AT_name, DW_FORM_strp, "main");
+  SubprogramDie.addAttribute(DW_AT_low_pc, DW_FORM_addr, 0x1000U);
+  SubprogramDie.addAttribute(DW_AT_high_pc, DW_FORM_addr, 0x2000U);
+
+  StringRef FileBytes = DG->generate();
+  MemoryBufferRef FileBuffer(FileBytes, "dwarf");
+  auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
+  EXPECT_TRUE((bool)Obj);
+  std::unique_ptr<DWARFContext> Ctx = DWARFContext::create(**Obj);
+
+  DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);
+  ASSERT_NE(nullptr, CU);
+  // Manually extracting DWARF DIE.
+  uint64_t DIEOffset = CU->getOffset() + CU->getHeaderSize();
+  uint64_t NextCUOffset = CU->getNextUnitOffset();
+  DWARFDebugInfoEntry DieInfo;
+  DWARFDataExtractor DebugInfoData = CU->getDebugInfoExtractor();
+  uint32_t Depth = 0;
+  ASSERT_TRUE(
+      DieInfo.extractFast(*CU, &DIEOffset, DebugInfoData, NextCUOffset, Depth));
+  DWARFDie Die(CU, &DieInfo);
+  ASSERT_TRUE(Die.isValid());
+  ASSERT_TRUE(Die.hasChildren());
+  // Since we have extracted manually DieArray is empty.
+  // Dump function should respect the default flags and print just current DIE,
+  // and not explore children.
+  SmallString<512> Output;
+  raw_svector_ostream OS(Output);
+  Die.dump(OS);
+  constexpr size_t NumOfLines = 3;
+  SmallVector<StringRef, NumOfLines> Strings;
+  SmallVector<StringRef, NumOfLines> ValidStrings = {
+      "0x0000000b: DW_TAG_compile_unit",
+      "              DW_AT_name	(\"/tmp/main.c\")",
+      "              DW_AT_language	(DW_LANG_C)"};
+  StringRef(Output).split(Strings, '\n', -1, false);
+  ASSERT_EQ(Strings.size(), NumOfLines);
+  for (size_t I = 0; I < NumOfLines; ++I)
+    EXPECT_EQ(ValidStrings[I], Strings[I]);
+}
+
+} // end anonymous namespace


        


More information about the llvm-commits mailing list