This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Don't print extended opcode operands if invalid
ClosedPublic

Authored by jhenderson on Jun 10 2020, 6:21 AM.

Details

Summary

Previously, if there was an error whilst parsing the operands of an extended opcode, the operands would be treated as zero and printed. This could potentially be slightly confusing. This patch changes the behaviour to print the raw bytes for the opcode instead.

Depends on D81562.

Diff Detail

Event Timeline

jhenderson created this revision.Jun 10 2020, 6:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 10 2020, 6:21 AM

Would not it be more useful if we dump a sequence of raw bytes, as we do for DWARF expressions? See DWARFExpression::print() and test llvm/test/tools/llvm-dwarfdump/X86/verify_broken_exprloc.s as an example.

Would not it be more useful if we dump a sequence of raw bytes, as we do for DWARF expressions? See DWARFExpression::print() and test llvm/test/tools/llvm-dwarfdump/X86/verify_broken_exprloc.s as an example.

Yes, it's probably possible somehow. I'll take a look. It would lead to slightly inconsistent behaviour with standard opcodes, where we don't have a known length for the operands, of course.

jhenderson edited the summary of this revision. (Show Details)

Print raw bytes of extended opcode on failure instead of nothing.

You may also want to add a couple of tests with an unrecognized opcode and premature termination, like these:

std::make_tuple(
    3, 9, 99,
    ValueAndLengths{{0x12345678, LineTable::Quad}}, ...
std::make_tuple(
    4, 9, 99,
    ValueAndLengths{{0x12345678, LineTable::Quad}}, ...
llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
814

It seems it is not possible to get here with an invalidated Cursor, no?

llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
1468

Maybe it is better to change DW_LNE_set_address to something different to emphasize that this test case goes to the default branch of switch (SubOpcode)?

1470

Should we add this if there are no raw bytes to report, especially when even opcode is missing? That space at the beginning looks quite untidy.

jhenderson marked 4 inline comments as done.

Address review comments, rewrite the raw byte printing, and added a few additional comments.

ikudrin accepted this revision.Jun 22 2020, 6:41 AM

Overall looks great.

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
814

Maybe it's worth to drop here a note about that Cursor is always valid here? So that a programmer coming across these lines would not be surprised why Cursor is checked in other branches, but not here?

937–946

I suppose that this might be simplified a bit using a do-while loop. Something like this:

uint8_t Byte = TableData.getU8(ByteCursor);
if (ByteCursor) {
  *OS << " (<parsing error>";
  do {
    *OS << format(" %2.2" PRIx8, Byte);
    Byte = TableData.getU8(ByteCursor);
  } while (ByteCursor);
  *OS << ")";
}

WDYT?

This revision is now accepted and ready to land.Jun 22 2020, 6:41 AM

Oh, and there are still no tests with unknown opcodes and truncated operands.

jhenderson marked an inline comment as done.Jun 22 2020, 7:29 AM

Oh, and there are still no tests with unknown opcodes and truncated operands.

Oops, missed that bit of your earlier comment. Thanks.

llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
937–946

I think that makes sense. I previously didn't do that, since it didn't seem to interact well with the ByteCursor.tell() < End, but looking at it again, I realise that bit is irrelevant, since we can just keep parsing until the end, and then ignore the error like we're already doing.

jhenderson marked 2 inline comments as done.

Add comment, use do/while, and add missing test case.

This revision was automatically updated to reflect the committed changes.