This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Fix crash when printing malformed DBG machine instructions
ClosedPublic

Authored by foad on Jul 25 2023, 3:53 AM.

Details

Summary

MachineVerifier does not check that DBG_VALUE, DBG_VALUE_LIST and
DBG_INSTR_REF have the expected number of operands, so printing them
(e.g. with -print-after-all) should not crash.

Diff Detail

Event Timeline

foad created this revision.Jul 25 2023, 3:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 25 2023, 3:53 AM
foad requested review of this revision.Jul 25 2023, 3:53 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 25 2023, 3:53 AM

This sounds like a good direction to take. As for why the verifier doesn't check things, IIRC there are some MIR tests out there where we don't bother to feed in any metadata, so that you can put meaningless DBG_VALUE's in MIR tests to test behaviours with little overhead. And which then leads to the behaviour you're patching against here.

Just to confirm my understanding: this is only suppressing printing the operands of debug instructions when there aren't enough operands, yes? It'd be unfortunate if we completely skipped printing an instruction because it was malformed, thus hiding it from developers.

llvm/lib/CodeGen/MachineInstr.cpp
1886–1899

I believe these should be >= operators rather than == . The instructions that can be variadic may have several operands or none, and we want the Variable and DebugLoc printed in those scenarios.

foad added a comment.Jul 25 2023, 5:24 AM

Just to confirm my understanding: this is only suppressing printing the operands of debug instructions when there aren't enough operands, yes? It'd be unfortunate if we completely skipped printing an instruction because it was malformed, thus hiding it from developers.

Correct, it only suppresses pretty-printing of the debug variable info as a comment.

As an alternative approach maybe all the accessors like getDebugVariableOp should check getNumOperands and return a failure value if the operand does not exist. But I do not want to get too deeply involved in this, I just wanted to stop llc -print-after-all from crashing.

llvm/lib/CodeGen/MachineInstr.cpp
1886–1899

OK. I was copying from MachineVerifier which does this:

// A fully-formed DBG_VALUE must have a location. Ignore partially formed
// DBG_VALUEs: these are convenient to use in tests, but should never get
// generated.
if (MI->isDebugValue() && MI->getNumOperands() == 4)
  if (!MI->getDebugLoc())
    report("Missing DebugLoc for debug instruction", MI);

But I guess that is slightly wrong for DBG_VALUE (should be >= 4), very wrong for DBG_VALUE_LIST (should be >= 2) and completely misses DBG_INSTR_REF.

(LGTM with the nit inline fixed)

llvm/lib/CodeGen/MachineInstr.cpp
1886–1899

Interesting, paging @StephenTozer , is the MachineVerifier accidentally skipping verification of DBG_VALUE_LIST?

Even in the verifier is wrong though, IMO this patch should use the greater-than test to ensure variadic info gets printed.

foad updated this revision to Diff 544821.Jul 27 2023, 9:34 AM

Use >=.

foad marked an inline comment as done.Jul 27 2023, 9:35 AM
arsenm accepted this revision.Aug 1 2023, 5:53 PM
This revision is now accepted and ready to land.Aug 1 2023, 5:53 PM
This revision was landed with ongoing or failed builds.Aug 2 2023, 12:28 AM
This revision was automatically updated to reflect the committed changes.