[PATCH] D76336: [DWARF] Emit DW_AT_call_pc for tail calls

Vedant Kumar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 19 15:22:38 PDT 2020


vsk marked an inline comment as done.
vsk added a comment.

This patch causes a 0.7% size increase in rela.debug_addr in a stage2 -gdwarf-5 build on Linux. That's ~569KB, similar to the size increase seen on Darwin (see my earlier comment). Here are the steps I took to measure:

F11599236: linux gdwarf-5 stage2 build.rtf <https://reviews.llvm.org/F11599236>

I rented out a VPS for the day to gather the data -- if at all possible please lmk by EOD today if you're interested in a different experiment.

> @dblaikie wrote:
>  why is this only relevant in optimized builds?

What @djtodoro said :). The features enabled by DW_TAG_call_site entries aren't useful/applicable at -O0. When call site entries /are/ useful, they always have to contain an address, otherwise the debugger can't figure out which call site entry to pick when stopped at a particular PC value.

Prior to this patch / currently, we only inserted an address into ~95% of call site entries (DW_AT_call_return_pc) -- the non-tail calling ones. We need the address of the tail-calling instruction, though, to make backtraces with artificial frames work properly.



================
Comment at: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:873
       const MCSymbol *PCAddr =
           (IsTail && !tuneForGDB())
               ? nullptr
----------------
djtodoro wrote:
> vsk wrote:
> > djtodoro wrote:
> > > Looks like the `dwarf::DW_AT_call_return_pc` is enough for GDB to distinguish that even for tail calls. Can we do the same for LLDB and avoid the `call_pc`?
> > > 
> > > 
> > I don't think that would be valid DWARF. The return pc for a tail call isn't given by the address of the instruction after after the tail-calling branch.
> > 
> > Are you sure GDB uses DW_AT_call_return_pc to figure out the address where the tail call was made?
> GCC generates the `low_pc` for DWARF 4 (actually GNU extension) and for the DWARF 5 DW_AT_call_return_pc for the call_site TAGs describing the tail calls.
> That is the address after the jump-like instruction for a tail call.
> 
> GDB understands that info and prints the artificial frames (the test case from the D76337):
> //gcc  -g -O2 tail.c -o gcc-tail-example//
>   ...
>   (gdb) r
>   Starting program: gcc-tail-example
>   Breakpoint 1, sink () at tail.c:4
>   4         x++;
>   (gdb) bt
>   #0  sink () at tail.c:4
>   #1  0x00000000004004a6 in func3 () at tail.c:9
>   #2  0x00000000004004b7 in func2 () at tail.c:13
>   #3  0x00000000004004d6 in func1 () at tail.c:18
>   #4  0x0000000000400367 in main () at tail.c:22
>   ...
> 
>   //GDB version 8.3.5//
>   //GCC version 4.9.3//
> 
> The same happens when using the latest LLVM Trunk (with the D73534 applied), since the DWARF 4 + GDB generates the same DWARF as GCC for the example.
> //clang -g -O2 tail.c -o tail-example//
>   ...
>   (gdb) r
>   Starting program: tail-example
>   Breakpoint 1, sink () at tail.c:4
>   4         x++;
>   (gdb) bt
>   #0  sink () at tail.c:4
>   #1  0x0000000000401149 in func3 () at tail.c:9      // the DW_AT_low_pc  is 0x401149 from the corresponding call_site
>   #2  0x0000000000401156 in func2 () at tail.c:13
>   #3  0x0000000000401169 in func1 () at tail.c:18
>   #4  0x0000000000401176 in main () at tail.c:22
>   ...
> 
Thanks for digging into this! This seems like a really weird quirk of gcc/gdb. To make this work, the debugger has to know that the DW_AT_call_return_pc for tail calls is bogus, and then find+subtract the correct offset from that address to to find the true call_pc. It seems simpler to just emit the correct call_pc to begin with.

In this patch, for the case where we're tuning for gdb in dwarf4 mode, I've omitted DW_AT_call_pc omission though (we'll keep emitting the strange DW_AT_call_return_pc -- I believe there's a test for this).


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

https://reviews.llvm.org/D76336





More information about the llvm-commits mailing list