[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