[lldb-dev] LLDB: Unwinding based on Assembly Instruction Profiling

Jason Molenda via lldb-dev lldb-dev at lists.llvm.org
Mon Oct 19 15:09:03 PDT 2015


> On Oct 19, 2015, at 2:54 PM, Jason Molenda via lldb-dev <lldb-dev at lists.llvm.org> wrote:

> Greg's original statement isn't correct -- about a year ago Tong Shen changed lldb to using eh_frame for the currently-executing frame.  While it is true that eh_frame is not guaranteed to describe the prologue/epilogue, in practice eh_frame always describes the epilogue (gdb wouldn't couldn't without this, with its much more simplistic unwinder).  Newer gcc's also describe the epilogue.  clang does not (currently) describe the epilogue.  Tong's changes *augment* the eh_frame with an epilogue description if it doesn't already have one.


Ahhh.... that paragraph was not clear.  I wrote that "in practice eh_frame always describes the epilogue".  I meant "always describes the prologue".

lldb needs the prologue description to step in to/step over functions correctly, at least at the first instruction of the function.

It's been five-six years since I worked on gdb's unwinder, but back when I worked on it, it didn't have multiple unwind schemes it could pick from, or the ability to use different unwind schemes in different contexts, or the ability to fall back to different unwind schemes.  That may not be true any longer, I don't know.  But back then it was an all-or-nothing approach, so if it was going to use eh_frame, it had to use it for everything.




> 
> gcc does have an "asynchronous unwind tables" option -- "asynchronous" meaning the unwind rules are defined at every instruction location.  But the last time I tried it, it did nothing.  They've settled on an unfortunate middle ground where eh_frame (which should be compact and only describe enough for exception handling) has *some* async unwind instructions.  And the same unwind rules are emitted into the debug_frame section, even if -fasynchronous-unwind-tables is used.  
> 
> In the ideal world, eh_frame should be extremely compact and only sufficient for exception handling.  debug_frame should be extremely verbose and describe the unwind rules at all unwind locations.
> 
> As Tamas says, there's no indication in eh_frame or debug_frame as to how much is described:  call-sites only (for exception handling), call-sites + prologue, call-sites + prologue + epilogue, or fully asynchronous.  It's a drag, if the DWARF committee ever has enough reason to break open the debug_frame format for some other changes, I'd like to get more information in there.
> 
> 
> Anyway, point is, we're living off of eh_frame (possibly "augmented") for the currently-executing stack frame these days.  lldb may avoid using the assembly unwinder altogether in an environment where it finds eh_frame unwind instructions for every stack frame.
> 
> 
> (on Mac, we've switched to a format called "compact unwind" -- much like the ARM unwind info that Tamas recently added support for, this is an extremely small bit of information which describes one unwind rule for the entire function.  It is only applicable or exception handling, it has no way to describe prologues/epilogues.  compact unwind is two 4-byte words per function.  lldb will use compact unwind / ARM unwind info for the non-zeroth stack frames.  It will use its assembly instruction profiler for the currently-executing stack frame.)
> 
> Hope that helps.
> 
> J
> 
> 
>> On Oct 15, 2015, at 2:56 AM, Tamas Berghammer via lldb-dev <lldb-dev at lists.llvm.org> wrote:
>> 
>> If we are trying to unwind from a non call site (frame 0 or signal handler) then the current implementation first try to use the non call site unwind plan (usually assembly emulation) and if that one fails then it will fall back to the call site unwind plan (eh_frame, compact unwind info, etc.) instead of falling back to the architecture default unwind plan because it should be a better guess in general and we usually fail with the assembly emulation based unwind plan for hand written assembly functions where eh_frame is usually valid at all address.
>> 
>> Generating asynchronous eh_frame (valid at all address) is possible with gcc (I am not sure about clang) but there is no way to tell if a given eh_frame inside an object file is valid at all address or only at call sites. The best approximation what we can do is to say that each eh_frame entry is valid only at the address what it specifies as start address but we don't make a use of it in LLDB at the moment.
>> 
>> For the 2nd part of the original question, I think changing the eh_frame based unwind plan after a failed unwind using instruction emulation is only a valid option for the PC where we tried to unwind from because the assembly based unwind plan could be valid at other parts of the function. Making the change for that 1 concrete PC address would make sense, but have practically no effect because the next time we want to unwind from the given address we use the same fall back mechanism as in the first case and the change would have only a very small performance gain.
>> 
>> Tamas
>> 
>> On Wed, Oct 14, 2015 at 9:36 PM Greg Clayton via lldb-dev <lldb-dev at lists.llvm.org> wrote:
>> 
>>> On Oct 14, 2015, at 1:02 PM, Joerg Sonnenberger via lldb-dev <lldb-dev at lists.llvm.org> wrote:
>>> 
>>> On Wed, Oct 14, 2015 at 11:42:06AM -0700, Greg Clayton via lldb-dev wrote:
>>>> EH frame can't be used to unwind when we are in the first frame because
>>>> it is only valid at call sites. It also can't be used in frames that
>>>> are asynchronously interrupted like signal handler frames.
>>> 
>>> This is not necessarily true, GCC can build them like that. I don't
>>> think we have a flag for clang/LLVM to create full async unwind tables.
>> 
>> Most compilers don't generate stuff that is complete, and if it is complete, I am not aware of any markings on EH frame that states it is complete. So we really can't use it unless we know the info is complete. Was there ever an additional augmentation letter that was attached to the complete EH frame info?
>> 
>> 
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
> 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list