This is supported (admittedly a little awkwardly) in DWARF with the 
DW_TAG_inline_subroutine DIE's in the  debug_info section of the DWARF.  They 
can expresses the nesting fully.  

I think we have all the data we need to do this right (*).

The missing part is making the right decision of which is the right frame in 
this virtual frame stack to choose depending on how you hit it.  For instance, 
when skipping the prologue to the beginning of the inline function, you really 
should choose the function whose prologue you were skipping, and then allow a 
"step-in" to get you into the function.  If you stop because of a breakpoint 
you should choose the frame in the virtual stack that the breakpoint was set 
in.  Etc.  I did this for straight line stepping.  So for instance if you are 
sitting at an instruction that is the start of a nested set of inlined 
functions, and do "step-in", lldb will not move the pc, but pretend it has 
stepped into the first of the inlined stacks.  Another step-in will get you to 
the next one, etc.  But there are a bunch of corner cases I haven't gotten to 
yet.

(*) Because you need to update this information in two places (whichever line 
gets chosen for the debug_line section, and the ranges of the 
DW_TAG_inline_subroutines, it allows an opportunity for fumbles that seems to 
trip up clang.  This has gotten better over time, but we still have a lot of 
reports where the range of lines in the line table and that in the debug_info 
don't match, making it very hard for lldb to figure out where it is.

It would be better to have this all expressed in one place so it would be 
easier to keep it coherent.  But that isn't necessary for lldb's purposes.

Jim


> On Sep 14, 2017, at 3:20 PM, Chris Quenelle <cq7...@gmail.com> wrote:
> 
> Have you guys considered going all the way and recording multiple layers
> of line information for the same range of instructions, and allowing the user 
> to jump up and down through the not-really-there function calls?  That seems
> like a very usefuil features for looking at optimized code.  You’d need an
> extension to the dwarf information of some kind.
> 
> Chris
> 
> 
> 
>> On Sep 14, 2017, at 11:29 AM, Jim Ingham via lldb-dev 
>> <lldb-dev@lists.llvm.org> wrote:
>> 
>> This is only tangential, but it is a known bug that when we stop on a line 
>> that starts an inlined block we don't pretend we're in the outer function 
>> first, so the user can "step-in" to the inlined function.  This is 
>> particularly notable when you have several nested levels of inlining 
>> starting at the same address, we say the naive thing - that we're in the 
>> innermost function, rather than setting up a set of fake step-in's that 
>> mirror the inline nesting.  If somebody wants to take a whack at fixing that 
>> it would be great.  Shouldn't be too hard.  We need to do other kinds of 
>> fakery as well, for instance if you have three levels of nested inlining and 
>> you set a breakpoint by specifying the middle function, then when you hit 
>> that breakpoint we should pretend we've just stepped into the middle 
>> function.
>> 
>> We handle these fictions with straight-line stepping when it encounters 
>> inlining pretty much okay.  But when we're just running to an address (and 
>> apparently when pushing past the prologue) we're not telling the right story.
>> 
>> Jim
>> 
>>> On Sep 14, 2017, at 3:20 AM, Tamas Berghammer via lldb-dev 
>>> <lldb-dev@lists.llvm.org> wrote:
>>> 
>>> Hi Carlos,
>>> 
>>> Thank your for looking into the LLDB failure. I looked into it briefly and 
>>> the issue is that we have have 2 function f and g where g is inlined into f 
>>> as the first call and this causes the first non-prologue line entry of f to 
>>> be inside the address range of g what means that when we step info f from 
>>> outside we will end up inside g instead. Previously the first line entry 
>>> for f matched with the start address of the inlined copy of g where LLDB 
>>> was able to handle the stepping properly.
>>> 
>>> For the concrete example you should compile 
>>> https://github.com/llvm-mirror/lldb/blob/26fea9dbbeb3020791cdbc46fbf3cc9d7685d7fd/packages/Python/lldbsuite/test/functionalities/inline-stepping/calling.cpp
>>>  with "/mnt/ssd/ll/git/build/host-release/bin/clang-5.0 -std=c++11 -g -O0 
>>> -fno-builtin -m32 --driver-mode=g++ calling.cpp" and then observe that 
>>> caller_trivial_2 have a DW_AT_low_pc = 0x8048790 and the inlined 
>>> inline_trivial_1 inside it have a DW_AT_low_pc = 0x8048793 but the first 
>>> line entry after "Set prologue_end to true" is at 0x8048796 while 
>>> previously it was at 0x8048793.
>>> 
>>> Tamas
>>> 
>>> On Thu, Sep 14, 2017 at 9:59 AM Carlos Alberto Enciso via lldb-dev 
>>> <lldb-dev@lists.llvm.org> wrote:
>>> Hi,
>>> 
>>> I have been working on a compiler issue, where instructions associated to 
>>> the function prolog are assigned line information, causing the debugger to 
>>> show incorrectly the beginning of the function body.
>>> 
>>> For a full description, please see:
>>> 
>>> https://reviews.llvm.org/D37625
>>> https://reviews.llvm.org/rL313047
>>> 
>>> The submitted patch caused some LLDB tests to fail. I have attached the log 
>>> failure.
>>> 
>>> I have no knowledge about the test framework used by LLDB.
>>> 
>>> What is the best way to proceed in this case?
>>> 
>>> Thanks very much for your feedback.
>>> 
>>> Carlos Enciso
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev@lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev@lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>> 
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
> 

_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Reply via email to