[PATCH] D142556: [DebugInfo] Merge partially matching chains of inlined locations

David Stenberg via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 25 08:26:58 PST 2023


dstenb created this revision.
dstenb added reviewers: aprantl, vsk, dblaikie, jmmartinez.
dstenb added a project: debug-info.
Herald added subscribers: pengfei, hiraditya.
Herald added a project: All.
dstenb requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

For example, if you have a chain of inlined funtions like this:

   1 #include <stdlib.h>
   2 int g1 = 4, g2 = 6;
   3
   4 static inline void bar(int q) {
   5   if (q > 5)
   6     abort();
   7 }
   8
   9 static inline void foo(int q) {
  10   bar(q);
  11 }
  12
  13 int main() {
  14   foo(g1);
  15   foo(g2);
  16   return 0;
  17 }

with optimizations you could end up with a single abort call for the two
inlined instances of foo(). When merging the locations for those inlined
instances you would previously end up with a 0:0 location in main().
Leaving out that inlined chain from the location for the abort call
could make troubleshooting difficult in some cases.

This patch changes DILocation::getMergedLocation() to try to handle such
cases. The function is rewritten to first find a common starting point
for the two locations (same subprogram and inlined-at location), and
then in reverse traverses the inlined-at chain looking for matches in
each subprogram. For each subprogram, the merge function will find the
nearest common scope for the two locations, and matching line and
column (or set them to 0 if not matching).

In the example above, you will for the abort call get a location in
bar() at 6:5, inlined in foo() at 10:3, inlined in main() at 0:0 (since
the two inlined functions are on different lines, but in the same
scope).

I have not seen anything in the DWARF standard that would disallow
inlining a non-zero location at 0:0 in the inlined-at function, and both
LLDB and GDB seem to accept these locations (with D142552 <https://reviews.llvm.org/D142552> needed for
LLDB to handle cases where the file, line and column number are all 0).
One incompatibility with GDB is that it seems to ignore 0-line locations
in some cases, but I am not aware of any specific issue that this patch
produces related to that.

With x86-64 LLDB (trunk) you previously got:

  frame #0: 0x00007ffff7a44930 libc.so.6`abort
  frame #1: 0x00005555555546ec a.out`main at merge.c:0

and will now get:

  frame #0: 0x[...] libc.so.6`abort
  frame #1: 0x[...] a.out`main [inlined] bar(q=<unavailable>) at merge.c:6:5
  frame #2: 0x[...] a.out`main [inlined] foo(q=<unavailable>) at merge.c:10:3
  frame #3: 0x[...] a.out`main at merge.c:0

and with x86-64 GDB (11.1) you will get:

  (gdb) bt
  #0  0x00007ffff7a44930 in abort () from /lib64/libc.so.6
  #1  0x00005555555546ec in bar (q=<optimized out>) at merge.c:6
  #2  foo (q=<optimized out>) at merge.c:10
  #3  0x00005555555546ec in main ()


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142556

Files:
  llvm/lib/IR/DebugInfoMetadata.cpp
  llvm/test/DebugInfo/MIR/X86/merge-inline-loc1.mir
  llvm/test/DebugInfo/MIR/X86/merge-inline-loc2.mir
  llvm/test/DebugInfo/MIR/X86/merge-inline-loc3.mir
  llvm/test/DebugInfo/MIR/X86/merge-inline-loc4.mir
  llvm/test/DebugInfo/X86/merge_inlined_loc.ll
  llvm/unittests/IR/MetadataTest.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142556.492124.patch
Type: text/x-patch
Size: 59108 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230125/3405abc2/attachment.bin>


More information about the llvm-commits mailing list