[PATCH] D49887: [DebugInfo] Add basic support for DWARF5 call site-related attributes

Vedant Kumar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 27 09:50:33 PDT 2018


vsk added a comment.

In https://reviews.llvm.org/D49887#1177851, @dblaikie wrote:

> Do you really want to implement all_calls? It seems like that's going to be difficult and expensive (in size). Looks like you're focussed  mostly on the tail call case, so why not aim for all_tail_calls?


Without all_calls, it's not possible to infer a backtrace for certain chains of calls. Consider stopping inside of bar() in this example:

  volatile int sink;
  
  void bar() __attribute__((noinline)) {
    sink++; //< foo() does not show up in the backtrace.
  }
  
  void foo() __attribute__((noinline)) {
    bar(); //< Tail call.
  }
  
  void quux() __attribute__((noinline)) {
    bar(); //< Tail call.
  }
  
  int main() __attribute__((disable_tail_calls)) {
    foo(); //< Not a tail call.
    return 0;
  }

The physical backtrace looks like:

  #0 bar
  #1 main

Without a TAG_call_site for 'foo' within 'main', it's not possible to complete the backtrace. The synthetic frame between 'bar' and 'main' could either be 'foo' or 'quux'.

> & why the special case of only describing the first call site for any given function - I mean, it's a space saving, but is that sustainable (if so, are you thinking about proposing a DWARF change to support this implementation choice?)? If not, what's the benefit in having that feature/quirk in the short term?

Describing only the first call site for a given callee isn't a long-term solution. The basic problem a debugger needs to solve (as I understand it :) is to find a unique path from one frame to another. To solve this problem in the general case, you'd need a TAG_call_site with both the call target and the return PC (address of the instruction after the call) for every call in the program. The return PC is the extra piece of information that allows a debugger to disambiguate between the multiple call chains which could complete a physical backtrace. That's because a return address is stored in a known location on the stack and can be probed for.

The benefit of having limited TAG_call_site information initially is that it's enough to prototype basic debugger support. The algorithm is: do a DFS on the call graph to find a path from one frame to another, and refuse to create synthetic tail call frames if there's more than one path. This has limitations. For example, this algorithm wouldn't be able to complete the backtrace in the example above. However, I think it'd be useful as a proof-of-concept which we can use to lower-bound debug info bloat and to evaluate backtrace quality improvements.

> (also, in general: what's your use case for this feature? It does seem like a rather expensive feature (in terms of debug info size) & I've not, myself, encountered particular uses/need for it as yet)

We have a lot of crash logs from optimized programs to symbolicate. I want this feature to make it easier to read these backtraces, much like inline frames do.


https://reviews.llvm.org/D49887





More information about the llvm-commits mailing list