[Lldb-commits] [PATCH] D138176: [dsymutil] Fix assertion: (Ref > InputDIE.getOffset()), function cloneDieReferenceAttribute

Jonas Devlieghere via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 14 10:34:06 PST 2022


JDevlieghere added a comment.

Last week I debugged this further. Here's what I believe is going on. Consider the following simplified example with two CUs and a type `Foo`.

  0x01: DW_TAG_compile_unit
  
  0x02: DW_TAG_class_type
          DW_AT_containing_type (0x11)
          DW_AT_name            ("Foo")
  
  0x03: DW_TAG_pointer_type
          DW_AT_type            (0x02 "Foo") 
  
  ...
  
  0x10: DW_TAG_compile_unit
  
  0x11: DW_TAG_class_type
         DW_AT_containing_type (0x11)
         DW_AT_name            ("Foo")
  
  ...

Assume that in the first compile unit, we have a relocation that causes us to keep the pointer to foo.

During the analysis phase, when looking for DIEs to keep, we encounter the definition of `Foo`. Through an ODR attribute (in this case `DW_AT_containing_type`) we see the same definition of `Foo` in the second CU. We decide to keep the definition in CU2 (0x11) and mark the decl context as having a canonical ODR DIE. As a result, we don't keep the definition in CU1.

During the emission phase, we encounter the pointer to foo again (0x03). As part of cloning, we go over its attributes and encounter 0x02 through the `DW_AT_type`. The canonical DIE in CU2 hasn't been cloned yet, so the `RefInfo.Clone` is false and so is the DeclContext's canonical DIE offset. As a result, we trip off the assertion because the reference (0x2) is less than the input DIEs offset (0x3) and therefore should already have been emitted. Instead, we should note the (forward) reference and fix it up later, which is what this patch does.

In the patch I called it a backward reference, because the original DIE comes before the DIE being emitted now, but as shown here, it really is a forward reference, so maybe it's better to keep the original naming.

This reproduces for several internal projects. The smallest one is an LTO build with 1.8 million lines of IR. I've been trying to reduce it with `llvm-reduce`, `delta` and `bugpoint` since last Thursday, but all of these tools are struggling with DI metadata and the size of the file. I'll give it another day or so but I'm not holding my breath this will generate anything that can be used as a test.

With the reduction running in the background, I've been trying to hand-craft a test that exposes the behavior I've described here, but with every DIE it becomes exponentially harder to trick dsymutil's algorithm into traversing the DIEs in the order you want.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138176/new/

https://reviews.llvm.org/D138176



More information about the lldb-commits mailing list