[llvm] [DebugInfo] DWARF Units without DIEs are okay (PR #88840)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 15 21:08:42 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-debuginfo

Author: Will Hawkins (hawkinsw)

<details>
<summary>Changes</summary>

Nothing prevents a DWARF Unit from having no DIEs. However, the API for interacting with DIE-less DWARF Units (through, e.g., getUnitDIE) is a little cumbersome and there are spurious warnings generated. This patch will prevent those warnings and makes it a little easier to work with a DIE-less DWARF Unit.

---
Full diff: https://github.com/llvm/llvm-project/pull/88840.diff


4 Files Affected:

- (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h (+1) 
- (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h (+4-2) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp (+11-6) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp (+8-1) 


``````````diff
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 421b84d644db64..543b0ff33617be 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -48,6 +48,7 @@ class DWARFDie {
   DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry *D) : U(Unit), Die(D) {}
 
   bool isValid() const { return U && Die; }
+  bool isValidUnit() const { return !!U; }
   explicit operator bool() const { return isValid(); }
   const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; }
   DWARFUnit *getDwarfUnit() const { return U; }
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index f20e71781f46be..597632ca8f8304 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -257,6 +257,8 @@ class DWARFUnit {
 
   std::shared_ptr<DWARFUnit> DWO;
 
+  bool DieExtractionSuccess;
+
 protected:
   friend dwarf_linker::parallel::CompileUnit;
 
@@ -442,9 +444,9 @@ class DWARFUnit {
 
   DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
     extractDIEsIfNeeded(ExtractUnitDIEOnly);
-    if (DieArray.empty())
+    if (!DieExtractionSuccess)
       return DWARFDie();
-    return DWARFDie(this, &DieArray[0]);
+    return DWARFDie(this, DieArray.empty() ? nullptr : &DieArray[0]);
   }
 
   DWARFDie getNonSkeletonUnitDIE(bool ExtractUnitDIEOnly = true,
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 30afa651ffc23a..a2aa07027d41ae 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -35,12 +35,17 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
   OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
      << ")\n";
 
-  if (DWARFDie CUDie = getUnitDIE(false)) {
-    CUDie.dump(OS, 0, DumpOpts);
-    if (DumpOpts.DumpNonSkeleton) {
-      DWARFDie NonSkeletonCUDie = getNonSkeletonUnitDIE(false);
-      if (NonSkeletonCUDie && CUDie != NonSkeletonCUDie)
-        NonSkeletonCUDie.dump(OS, 0, DumpOpts);
+  DWARFDie CUDie = getUnitDIE(false);
+  if (CUDie.isValidUnit()) {
+    if (CUDie.isValid()) {
+      CUDie.dump(OS, 0, DumpOpts);
+      if (DumpOpts.DumpNonSkeleton) {
+        DWARFDie NonSkeletonCUDie = getNonSkeletonUnitDIE(false);
+        if (NonSkeletonCUDie && CUDie != NonSkeletonCUDie)
+          NonSkeletonCUDie.dump(OS, 0, DumpOpts);
+      }
+    } else {
+      OS << "<compile unit has no DIEs>\n\n";
     }
   } else {
     OS << "<compile unit can't be parsed!>\n\n";
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 9f455fa7e96a7e..8cc4039b86ba49 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -370,6 +370,7 @@ void DWARFUnit::clear() {
   SU = nullptr;
   clearDIEs(false);
   AddrDieMap.clear();
+  DieExtractionSuccess = true;
   if (DWO)
     DWO->clear();
   DWO.reset();
@@ -401,6 +402,10 @@ void DWARFUnit::extractDIEsToVector(
       ((AppendCUDie && Dies.empty()) || (!AppendCUDie && Dies.size() == 1)) &&
       "Dies array is not empty");
 
+  if (DIEOffset == NextCUOffset) {
+    return;
+  }
+
   // Fill Parents and Siblings stacks with initial value.
   Parents.push_back(UINT32_MAX);
   if (!AppendCUDie)
@@ -468,8 +473,10 @@ void DWARFUnit::extractDIEsToVector(
 }
 
 void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
-  if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
+  if (Error e = tryExtractDIEsIfNeeded(CUDieOnly)) {
+    DieExtractionSuccess = false;
     Context.getRecoverableErrorHandler()(std::move(e));
+  }
 }
 
 Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/88840


More information about the llvm-commits mailing list