Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DebugInfo] Report errors when DWARFUnitHeader::applyIndexEntry fails #89156

Merged
merged 4 commits into from
Apr 23, 2024

Conversation

bulbazord
Copy link
Member

Motivation: LLDB is able to report errors about these scenarios whereas LLVM's DWARF parser only gives a boolean success/fail. I want to migrate LLDB to using LLVM's DWARFUnitHeader class, but I don't want to lose some of the error reporting, so I'm adding it to the LLVM class first.

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 17, 2024

@llvm/pr-subscribers-debuginfo

Author: Alex Langford (bulbazord)

Changes

Motivation: LLDB is able to report errors about these scenarios whereas LLVM's DWARF parser only gives a boolean success/fail. I want to migrate LLDB to using LLVM's DWARFUnitHeader class, but I don't want to lose some of the error reporting, so I'm adding it to the LLVM class first.


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

2 Files Affected:

  • (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h (+1-1)
  • (modified) llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp (+23-7)
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index f20e71781f46be..80c27aea893123 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -85,7 +85,7 @@ class DWARFUnitHeader {
                 uint64_t *offset_ptr, DWARFSectionKind SectionKind);
   // For units in DWARF Package File, remember the index entry and update
   // the abbreviation offset read by extract().
-  bool applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
+  Error applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
   uint64_t getOffset() const { return Offset; }
   const dwarf::FormParams &getFormParams() const { return FormParams; }
   uint16_t getVersion() const { return FormParams.Version; }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 9f455fa7e96a7e..985566ad329f63 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -98,8 +98,12 @@ void DWARFUnitVector::addUnitsImpl(
         if (!IndexEntry)
           IndexEntry = Index.getFromOffset(Header.getOffset());
       }
-      if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
-        return nullptr;
+      if (IndexEntry) {
+        if (Error ApplicationErr = Header.applyIndexEntry(IndexEntry)) {
+          Context.getWarningHandler()(std::move(ApplicationErr));
+          return nullptr;
+        }
+      }
       std::unique_ptr<DWARFUnit> U;
       if (Header.isTypeUnit())
         U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
@@ -334,21 +338,33 @@ Error DWARFUnitHeader::extract(DWARFContext &Context,
   return Error::success();
 }
 
-bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
+Error DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
   assert(Entry);
   assert(!IndexEntry);
   IndexEntry = Entry;
   if (AbbrOffset)
-    return false;
+    return createStringError(errc::invalid_argument,
+                             "DWARF package unit from offset 0x%8.8" PRIx64
+                             " has a non-zero abbreviation offset",
+                             Offset);
+
   auto *UnitContrib = IndexEntry->getContribution();
   if (!UnitContrib ||
       UnitContrib->getLength() != (getLength() + getUnitLengthFieldByteSize()))
-    return false;
+    return createStringError(errc::invalid_argument,
+                             "DWARF package unit at offset 0x%8.8" PRIx64
+                             "has an inconsistent index",
+                             Offset);
+
   auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
   if (!AbbrEntry)
-    return false;
+    return createStringError(errc::invalid_argument,
+                             "DWARF package unit at offset 0x%8.8 " PRIx64
+                             " mising abbreviation column",
+                             Offset);
+
   AbbrOffset = AbbrEntry->getOffset();
-  return true;
+  return Error::success();
 }
 
 Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,

@bulbazord
Copy link
Member Author

I realize there are no tests for this currently, I'm working through that but may need some help. :)

@bulbazord
Copy link
Member Author

Okay, I've added some tests and made sure that they actually test all the relevant code paths. This is good to review now! 😄

Comment on lines 351 to 356
auto *UnitContrib = IndexEntry->getContribution();
if (!UnitContrib ||
UnitContrib->getLength() != (getLength() + getUnitLengthFieldByteSize()))
return false;
return createStringError(errc::invalid_argument,
"DWARF package unit at offset 0x%8.8" PRIx64
" has an inconsistent index",
Offset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this clause is covering two things that should be reported separately: the lack of a unit and the length of the contribution not matching the expected length. The latter could be part of the error message (e.g. expected x, actual y).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can split them into separate cases and then test them separately (I think). I'll also update the error message :)

Copy link
Contributor

@felipepiovezan felipepiovezan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
I find it surprising that, looking for the word "package" in the dwarf 5 spec yields the first result in section 7, which is usually reserved for the finer points of the data representation

Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me

Motivation: LLDB is able to report errors about these scenarios whereas
LLVM's DWARF parser only gives a boolean success/fail. I want to migrate
LLDB to using LLVM's DWARFUnitHeader class, but I don't want to lose
some of the error reporting, so I'm adding it to the LLVM class first.
Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@bulbazord bulbazord merged commit 1a8935a into llvm:main Apr 23, 2024
4 checks passed
@bulbazord bulbazord deleted the apply-index-entry branch April 23, 2024 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants