Live data from Hacker News

Frame pointers vs. DWARF – my verdict

rwmj.wordpress.com

21–30 of 67 posts

Re: Frame pointers vs. DWARF – my verdict

#21

The article points out that the kernel uses ORC instead of DWARF for unwinding. I wonder if that could ever become an option in userspace? I imagine that if all you’re interested in is stack traces, instead of debugging (which DWARF is designed for), ORC would be a very nice performance win. And it’s not as if they’re mutually exclusive, either: there’s no reason why a binary or debuginfo couldn’t just ship both. In…

> In any case, the runtime performance hit of frame pointers is quite high

That's not true at all. It's in some very rare cases. Firefox I think at this point ships with framepointers enabled and so does every M1/M2 mac app and all iOS applications as it's mandatory for the calling convention on Apple.

Re: Frame pointers vs. DWARF – my verdict

#23
post #16

> But collecting the whole stack would consume far too much storage, so by default it only collects the first 8K. Many userspace stacks will be larger than this, in which case the data collection will simply be incomplete – it will never be possible to recover the full stack trace. Yeah, doing an 8KB memcopy for every profile sample sounds like a lot of overhead. Is DWARF unwinding so slow that that is actually faste…

> Is DWARF unwinding so slow that that is actually faster?

No. The only reason it works like this is because the upstream Linux kernel has thus far rejected in-kernel dwarf unwinders, but copying the stack is simpler and available / implemented.

Re: Frame pointers vs. DWARF – my verdict

#24
post #6

Big advantage for DWARF2 over frame pointers is that it actually works for unwinding on aarch64.

Can you give more detail?

AFAIK frame pointers work fine for unwinding on aarch64. And on aarch64 the gcc default is not to omit frame pointers and IIRC when the default was switched at some point it was treated as a bug and reverted (not sure if required in the ABI or just strongly preferred by the community). So IME generally unwinding with frame pointers on aarch64 works more often than on amd64 since you don’t have to recompile the world.

Re: Frame pointers vs. DWARF – my verdict

#25

Earlier quoted context omitted.

Right, x86-64 offers eight extra register names† (r8 through r15). If you choose to go from x86-without-frame-pointer to x86-64-with-frame-pointer you gained 7 register names which is huge. This makes the case where that one extra register name makes all the difference much rarer, arguably turning it from "I demand a compiler flag" to "Let's just hand-write the machine code for this one very special routine if our pe…

I think generally the talk about "there are not enough registers" ignore pipelining and register renaming way too much. The loss of performance of the frame pointer register even on x86 is not that problematic, and on x86_64 it's completely negligible unless you're in a tight switch heavy interpreter loop.

Register renaming doesn’t significantly address the impact of reducing the number of architectural registers available to the compiler. With fewer register names available, the compiler will spill locals to stack more often, and register renaming doesn’t help - memory renaming is needed to really mitigate this.

But i agree the impact of preserving frame pointers is generally quite small and doesn’t often actually need mitigation - on amd64 there’s not much impact from losing 1 more of 16 arch registers.

Re: Frame pointers vs. DWARF – my verdict

#26

The article points out that the kernel uses ORC instead of DWARF for unwinding. I wonder if that could ever become an option in userspace? I imagine that if all you’re interested in is stack traces, instead of debugging (which DWARF is designed for), ORC would be a very nice performance win. And it’s not as if they’re mutually exclusive, either: there’s no reason why a binary or debuginfo couldn’t just ship both. In…

> In any case, the runtime performance hit of frame pointers is quite high That's not true at all. It's in some very rare cases . Firefox I think at this point ships with framepointers enabled and so does every M1/M2 mac app and all iOS applications as it's mandatory for the calling convention on Apple.

On AArch64 I think it's cheaper because losing one register doesn't hurt as much, since you've got twice as many.

Re: Frame pointers vs. DWARF – my verdict

#27
post #2

Nice analysis. It would be interesting to see comparison to Intel LBR. Also would be nice to know how profiling unwinding is done on Windows (maybe someone knows how to summon Bruce Dawson).

IIUC Windows implements in-kernel unwinding using FPO debug data embedded in every executable.

Re: Frame pointers vs. DWARF – my verdict

#28

Earlier quoted context omitted.

> To summarize, unwinding via frame pointers does not miss any information that would be collected with DWARF unwinding. Everything can be recovered later at symbolization time. The real issue with DWARF based unwinding/symbolication is that it's really complex on the user experience around it. We at Sentry support stack walking from minidumps, yet we often cannot unwind on Linux platforms on the server because execu…

Couldn't this be solved by uploading the binaries along with the crash dumps, if you don't already have a copy of it, as determined by checking hashes or something?

The debug info is usually stripped out of the binaries for Linux distros and has to be installed separately. debuginfod is supposed to make possible to download the debug info in a distro-agnostic way based on the build ID embedded in the binaries.

Re: Frame pointers vs. DWARF – my verdict

#29

Uh... [Begin flashback] 2012: A change made in GCC 4.7 allowed optimization to reschedule and defer the push of the frame pointer that previously occurred in the function prologue whenever frame pointers were enabled. When binaries are profiled using frame pointers, incorrect call chains are derived whenever a sample is taken between the top of the function and the instruction that pushes the frame pointer. I complai…

I cannot comment on whether “everyone” is oblivious but yes, this is still the case - frame pointer based unwinding sometimes skips the caller when the IP is sampled before the callee sets up a frame.

This is also common for samples in leaf functions.

compiler & tool chain folks tend to think (quite justifiably imo) that this and similar stuff is fine because dwarf allows reconstructing everything perfectly. The problem is just that the user experience of dwarf-based unwinding is poor, because the only implemented method in Linux is sampling the contents of the stack and doing the unwind in post processing.

Post reply on HN