This is an archive of the discontinued LLVM Phabricator instance.

[Debuginfo][llvm-dwarfutil] Add check for unsupported debug sections.
ClosedPublic

Authored by avl on Apr 12 2022, 11:17 AM.

Details

Summary

Current DWARFLinker implementation does not support some debug sections
(mainly DWARF v5 sections). This patch adds diagnostic for such sections.
The error would be displayed for critical(such that could not be removed)
sections and the source file would be skipped. Other unsupported sections
would be removed and warning message should be displayed. The zero exit
status would be returned for both cases.

Depends on D86539

Diff Detail

Event Timeline

avl created this revision.Apr 12 2022, 11:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 12 2022, 11:17 AM
avl requested review of this revision.Apr 12 2022, 11:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 12 2022, 11:17 AM

The error would be displayed for critical(such that could not be removed) sections and the source file would be skipped. Other unsupported sections would be removed and warning message should be displayed

I have concerns about this difference in behaviour between "critical" and "non-critical" sections:

  1. I assume this code has a DWARF version check, but if not, the assumption of what is "critical"/"non-critical" is going to fall down the next time a DWARF standard is published (potentially). Even then, developers of this tool will have to remember to update this list when adding DWARFv6 etc support. It feels fragile.
  2. There's an assumption here that all .debug_* sections are part of the DWARF standard. I know of at least one downstream usage within my company where we've extended the DWARF spec by adding a new section. This was deliberately called .debug_* to ensure it got stripped by tools when stripping debug information, but is, if I'm not mistaken, otherwise independent of the debug information. By having a hard-coded list, we'll have to carry a private downstream patch around or anybody using this tool will end up having their debug data corrupted. Whilst I acknowledge that we don't need to worry about downstream users that much, I do think it's pointing to the fact that this is the wrong approach again, although I don't have a concrete answer to what the right approach should be.
  3. What determines what is a "critical" versus a "non-critical" section? Surely that depends upon the consumer as well as the structure of the DWARF?
llvm/test/tools/llvm-dwarfutil/ELF/error-unsupported-types.test
4 ↗(On Diff #422300)

Why does this use a canned binary rather than yaml2obj?

llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
284

This comment needs reflowing too.

avl added a comment.Apr 13 2022, 1:06 AM

The error would be displayed for critical(such that could not be removed) sections and the source file would be skipped. Other unsupported sections would be removed and warning message should be displayed

I have concerns about this difference in behaviour between "critical" and "non-critical" sections:

  1. I assume this code has a DWARF version check, but if not, the assumption of what is "critical"/"non-critical" is going to fall down the next time a DWARF standard is published (potentially). Even then, developers of this tool will have to remember to update this list when adding DWARFv6 etc support. It feels fragile.

There is no check for DWARF version at the moment. I think it would be good to add.

At the moment DWARFLinker has partial support for DWARF v5 and partial support for DWARF v4 sections(it does not update .debug_macinfo, does not handle debug_types).

  1. There's an assumption here that all .debug_* sections are part of the DWARF standard. I know of at least one downstream usage within my company where we've extended the DWARF spec by adding a new section. This was deliberately called .debug_* to ensure it got stripped by tools when stripping debug information, but is, if I'm not mistaken, otherwise independent of the debug information. By having a hard-coded list, we'll have to carry a private downstream patch around or anybody using this tool will end up having their debug data corrupted. Whilst I acknowledge that we don't need to worry about downstream users that much, I do think it's pointing to the fact that this is the wrong approach again, although I don't have a concrete answer to what the right approach should be.

The same assumption is used in other llvm parts f.e. ELFObjcopy.cpp:

static bool isDebugSection(const SectionBase &Sec) {
  return StringRef(Sec.Name).startswith(".debug") ||
         StringRef(Sec.Name).startswith(".zdebug") || Sec.Name == ".gdb_index";
}

To resolve that case with custom sections we can add option --keep-section=debug_custom.

  1. What determines what is a "critical" versus a "non-critical" section? Surely that depends upon the consumer as well as the structure of the DWARF?

The difference is whether section might be safely dropped or not(in other words whether section is important for optimizations done by tool). f,e,

a) the tool need to handle address ranges for garbage collection. Since the tool does not able to process .debug_rnglists section then it could not do garbage collection at all. This is critical section.

b) .debug_cu_index is not used for garbage collection. But it references debug_info which rebuilt by tool. the tool does not update .debug_cu_index so it becomes invalid after garbage collection. Though it may be easily dropped. This is not critical section.

llvm/test/tools/llvm-dwarfutil/ELF/error-unsupported-types.test
4 ↗(On Diff #422300)

yaml2obj does not support debug_types.

To resolve that case with custom sections we can add option --keep-section=debug_custom.

I think this would be sensible. It would then be fairly easy to add downstream a more maintainable patch that always has that option enabled for the specific section.

  1. What determines what is a "critical" versus a "non-critical" section? Surely that depends upon the consumer as well as the structure of the DWARF?

The difference is whether section might be safely dropped or not(in other words whether section is important for optimizations done by tool). f,e,

a) the tool need to handle address ranges for garbage collection. Since the tool does not able to process .debug_rnglists section then it could not do garbage collection at all. This is critical section.

b) .debug_cu_index is not used for garbage collection. But it references debug_info which rebuilt by tool. the tool does not update .debug_cu_index so it becomes invalid after garbage collection. Though it may be easily dropped. This is not critical section.

Thanks, I see.

llvm/test/tools/llvm-dwarfutil/ELF/error-unsupported-types.test
4 ↗(On Diff #422300)

Do you need a fully fledged .debug_types though, or could you just use a regular section called .debug_types (containing either garbage or is empty etc)?

avl added inline comments.Apr 13 2022, 3:55 AM
llvm/test/tools/llvm-dwarfutil/ELF/error-unsupported-types.test
4 ↗(On Diff #422300)

yes, I do. If it is an empty .debug_types section or section filled with garbage then the error like "broken type unit" is displayed. It does not allow to get that: "type units are not currently supported" diagnostic.

avl updated this revision to Diff 446962.Jul 22 2022, 1:26 PM

rebased.

JDevlieghere added inline comments.Jul 22 2022, 1:41 PM
llvm/lib/DWARFLinker/DWARFLinker.cpp
2427–2430

I generally expect errors to be fatal. Should this be a warning instead? Something like:

warning: .debug_rnglists is not currently supported: section will be skipped

llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp
215–221

This seems like a good candidate for a string switch.

avl added inline comments.Jul 23 2022, 12:27 AM
llvm/lib/DWARFLinker/DWARFLinker.cpp
2427–2430

I used error vs warning to differentiate a case when 'critical' or not 'critical' section is met. But I think it could be done by different message instead:

warning: .debug_rnglists is not currently supported: compile unit will be skipped

vs

warning: .gdb-index is not currently supported: section will be skipped

thus, will make both cases to be warning.

avl added inline comments.Jul 23 2022, 1:17 AM
llvm/lib/DWARFLinker/DWARFLinker.cpp
2427–2430

To make things explicit, after this patch is applied following messages would also be shown by dsymutil:

warning: type units are not currently supported: compile unit will be skipped
warning: .debug_rnglists is not currently supported: compile unit will be skipped
warning: .debug_loclists is not currently supported: compile unit will be skipped
warning: .debug_macinfo is not currently supported: compile unit will be skipped
warning: .debug_macro is not currently supported: compile unit will be skipped
avl updated this revision to Diff 447045.Jul 23 2022, 1:40 AM

addressed comments.

dblaikie added inline comments.Jul 24 2022, 11:59 PM
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
9

Might be good to check these errors all include more info, like a file name - as it stands (what's actually FileCheck'd here) it'd be a pretty unactionable/opaque error message.

To do this you'd probably have to put the file in a particular location, like %t-filename.o then regex match in the CHECK line to skip the prefix and just look for erorr message {{.*}}-filename.o or the like.

Maybe it'd be simpler/more accurate for the error message to say "file will be skipped" - since I assume that's what's going to happen, yeah? Even if the file contains multiple units (could be multiple compile units from LTO, and/or multiple type units as well)

jhenderson added inline comments.Jul 25 2022, 7:25 AM
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
9

This check does check the filename though? That's what the [[FILE]] bit is doing...

avl added inline comments.Jul 25 2022, 9:17 AM
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
9

Might be good to check these errors all include more info, like a file name - as it stands (what's actually FileCheck'd here) it'd be a pretty unactionable/opaque error message.

To do this you'd probably have to put the file in a particular location, like %t-filename.o then regex match in the CHECK line to skip the prefix and just look for erorr message {{.*}}-filename.o or the like.

The error message already contains file name. [[FILE]] matches with file name.

Maybe it'd be simpler/more accurate for the error message to say "file will be skipped" - since I assume that's what's going to happen, yeah? Even if the file contains multiple units (could be multiple compile units from LTO, and/or multiple type units as well)

yes, I think that would be better message: "file will be skipped". Thanks.

dblaikie added inline comments.Jul 25 2022, 9:18 AM
llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test
9

Oh, right, sorry!

This revision is now accepted and ready to land.Jul 25 2022, 11:56 AM
avl updated this revision to Diff 447641.Jul 26 2022, 4:08 AM

changed text of warning message.

This revision was landed with ongoing or failed builds.Jul 26 2022, 5:27 AM
This revision was automatically updated to reflect the committed changes.