[lldb-dev] Hiding trampoline functions from the backtrace, is it possible ?
Jim Ingham via lldb-dev
lldb-dev at lists.llvm.org
Wed Sep 25 11:16:00 PDT 2019
In a pure world, debugger users would use "step-in" when they meant to step in, and step-over when they don't. However, it's actually pretty natural to say "step-in" and then just keep hitting return, and expect the debugger to trace through your code "doing the right thing".
When you've stopped at this line:
printf("This really is a function you know.\n");
almost nobody wants to step into the code for printf. They want the debugger to turn their "step-in" into a "step-over". So you have to have some criteria for when users probably do mean "step-in". In lldb & gdb that starts with a simple "does it have debug info" test. If not, step-in -> step-over.
We've also added other criteria - for instance by default we don't step into anything from std:: since there lots of inlined code from std:: that has debug info but people still don't want to step into it.
But that means if there are any patterns on the system that pass through code without debug information but then end up in code that might have debug information, the debugger needs to intervene so that step-in continues to be step-in in those cases. Those patterns are what lldb calls Trampolines. For instance, cross-library call shims are trampolines, since you generally first step into the shim which is a symbol without debug information, then go through some loader code to resolve the symbol and then tail-call to the symbol. lldb is expected to automatically follow through the loader code into the real symbol. Similarly, objc_msgSend is a trampoline in this sense. And also, because we don't want to stop in general std:: code, the function calling layers that std::function goes through to invoke the function it holds also constitute a trampoline. Shafik added a trampoline handler for these not too long ago.
It isn't strictly a compiler notion, and I certainly didn't adopt the term from clang. I'm pretty sure that's what gdb calls it, or maybe I just made it up, I can't really remember.
Just marking a symbol somehow doesn't help lldb, in this regard, since it doesn't tell us how to get to the "real" target of the trampoline.
But more pertinent to this conversation, I don't think the project of eliding some stack frames to make backtraces easier to read should be linked to the notion of the symbol being a trampoline, since it has much wider usage. If there were a system that marked frames for elision, it would be fine if "has DW_AT_artificial" was one of the ways to decide a frame should be elided. But that should just be one pattern we look for, not the way we implement the feature.
> On Sep 25, 2019, at 5:51 AM, paul.robinson at sony.com wrote:
>> -----Original Message-----
>> From: lldb-dev [mailto:lldb-dev-bounces at lists.llvm.org] On Behalf Of Jim
>> Ingham via lldb-dev
>> Sent: Tuesday, September 24, 2019 4:19 PM
>> To: Nat!
>> Cc: LLDB
>> Subject: Re: [lldb-dev] Hiding trampoline functions from the backtrace, is
>> it possible ?
>>> On Sep 24, 2019, at 11:36 AM, Nat! via lldb-dev <lldb-
>> dev at lists.llvm.org> wrote:
>>> On 24.09.19 19:28, Jim Ingham wrote:
>>>> We've had many requests to elide some classes of entries in backtraces
>> - like to mirror the Xcode display I mentioned previously. Most of these
>> requests don't depend on the functions being marked artificial. So if
>> we're going to do this, something more general than just "marked
>> artificial" -> elided anyway.
>>> Having done a little further research... Artificial won't work for
>> general cases anyway, since it's restricted to inline code (for some
>> reason) on gcc and clang. I wonder why, since for a function the only real
>> effect is to emit DW_AT_artificial (AFAIK). The restriction seems
>> arbitrary and DWARF wouldn't mind.. But the compilers do, so it seems out
> Clang puts DW_AT_artificial on implicit member functions, which tend to be
> inlined due to their simplicity; explicit functions marked as 'inline' in
> the source would not be flagged as artificial. There's no direct link
> between inline and artifical.
> I grepped for "trampoline" in Clang source; it occurs only in comments,
> and never with respect to functions spontaneously created by the compiler.
> If they're there, they're called something else.
>>> DW_AT_trampoline isn't supported by llvm. As I read the description of
>> DW_AT_trampoline, its more like a hardcoded vector (a->b), so not useful
>> for cases like objc_msgSend, where you don't know the destination a
>>> If I look at the DWARF spec, I don't see any other way to mark a
>> function as "boring". I still think this would be a good thing, as this
>> would be useful for other debuggers as well, which could instantly work.
>> Also a lot of code in the lldb Trampoline classes, for step-in and step-
>> out could probably just be removed.
>> I don't think that is right for "step-in". As you said above, in the
>> classic example of a trampoline: objc_msgSend you can't statically know
>> the destination. So the DWARF can't help resolve this; you would still
>> need to do the work the lldb trampoline classes do at runtime.
>> step-out past trampolines could just "keep stepping past boring
>> functions". There's no need to support this for ObjC - at least the Apple
>> & NeXT versions - since the dispatch function is a tail call function.
>> But we do do something like for Swift. But that part is very little code
>> compared to figuring how to step in correctly.
>>> lldb-dev mailing list
>>> lldb-dev at lists.llvm.org
>> lldb-dev mailing list
>> lldb-dev at lists.llvm.org
More information about the lldb-dev