-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[DebugInfo] Report errors when DWARFUnitHeader::applyIndexEntry fails #89156
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
Conversation
@llvm/pr-subscribers-debuginfo Author: Alex Langford (bulbazord) ChangesMotivation: 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:
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,
|
I realize there are no tests for this currently, I'm working through that but may need some help. :) |
ce40cc2
to
8d5530e
Compare
Okay, I've added some tests and made sure that they actually test all the relevant code paths. This is good to review now! 😄 |
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); |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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 :)
There was a problem hiding this 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
8d5530e
to
dad34ba
Compare
There was a problem hiding this 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.
dad34ba
to
8f9bcd1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
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.