What everybody in this discussion seems to miss is that you don't need to unwind the DWARF data structures during profiling time , you are free to convert DWARF to a fast-lookup data structure on the machine. DWARF needs to support every CPU under the sun. Every unwinder on the other hand is CPU-specific. For prodfiler.com's continuous in-production unwinding, we convert DWARF into something compact and fast-to-looku…
Frame pointers vs. DWARF – my verdict
51–60 of 67 posts
Re: Frame pointers vs. DWARF – my verdict
#52Earlier quoted context omitted.
Allowing processes to sniff each others stacks has some fairly obvious security issues.
I don’t understand your concern - what about this would involve one process sniffing another process’s memory? The kernel would still be doing the unwinding, just not in the NMI handler.
Re: Frame pointers vs. DWARF – my verdict
#53Re: Frame pointers vs. DWARF – my verdict
#54Earlier quoted context omitted.
I don’t understand your concern - what about this would involve one process sniffing another process’s memory? The kernel would still be doing the unwinding, just not in the NMI handler.
Wouldn't all your kernel stacks then end up in whatever this handler is? Why not implement your approach and mail it to LKML :-)
> Why not implement your approach and mail it to LKML :-)
because this would still be an in-kernel dwarf unwinder and I would expect an instant reject, and because I am lazy and/or don’t care enough about this problem or linux to work on it. Even if people could be persuaded, I don’t have the interest or temperance to debate this with LKML.
Re: Frame pointers vs. DWARF – my verdict
#55While DWARF unwind info doesn't use that many bytes, but unfortunately reading and parsing that information is quite expensive.
For that reason I've developed a new unwinder that uses custom unwind information derived from DWARF (https://www.polarsignals.com/blog/posts/2022/11/29/profiling..., previously discussed in https://news.ycombinator.com/item?id=33788794) that runs in BPF. This new compact representation can be binary searched easily and each unwind row has a size of 16 bytes. I am currently working on reducing it down to ~10 bytes.
All the code is fully OSS (Apache 2.0 for userspace and GPL for BPF), and part of the Parca project (https://github.com/parca-dev/parca-agent). We've also given a talk this year in FOSDEM going deeper into how we made it scale for many big processes.
Re: Frame pointers vs. DWARF – my verdict
#56What everybody in this discussion seems to miss is that you don't need to unwind the DWARF data structures during profiling time , you are free to convert DWARF to a fast-lookup data structure on the machine. DWARF needs to support every CPU under the sun. Every unwinder on the other hand is CPU-specific. For prodfiler.com's continuous in-production unwinding, we convert DWARF into something compact and fast-to-looku…
prodfiler clearly has a market. It would be interesting to see the approach as something standard in the kernel tree, perhaps it can be added to perf's synthesis, etc. There is already BPF based profiling within perf to avoid file descriptor overheads. If engineering resources are the issue then this could be a good GSoC project: https://wiki.linuxfoundation.org/gsoc/2023-gsoc-perf
As this will take few years, in the meantime I've developed a DWARF-based unwinder in BPF [0]. Some perf maintainers showed interest in this, so thanks for bringing up the GSoC project idea, didn't occur to me!
Re: Frame pointers vs. DWARF – my verdict
#57Earlier quoted context omitted.
Someone from prodfiler appears to be explaining in this thread https://news.ycombinator.com/item?id=34806693
For every running application turn DWARF data into BPF maps. Does this scale?
Re: Frame pointers vs. DWARF – my verdict
#58I built my company's in-house mobile crash reporter ~ 2013, based on experience building a similar system at an earlier startup. At the startup I used Google breakpad on both Android and iOS, doing all the unwinding and symbolication on the backend. iOS at least made this easy because Apple makes dSYMs readily available. On Android, you simply can't get system symbols. So you essentially can't unwind OS symbols on Android.
At current company I used PLCrashReporter on iOS. Unwinding occurs on device. Symbolication on the backend.
I tried everything with Android for native code crashes, starting with breakpad minidumps, then using every available unwinder option on Android: corkscrew, the Android fork of libunwind, the official libunwind, whatever custom unwinder Android eventually wrote. None of them work reliably for native code crashes. And good luck tracing from native code back into the ART frames.
In the end what ending up being most reliable was including the last few thousand lines of logcat (grabbed upon the app restarting after a crash since you can't reliably grab it inside the crash handler). Android's OOB crash handler for some crashes (with recent Android versions) dumps full stacks of every thread including native code and ART frames to logcat. So the crash SDK looks for that in the logcat output and includes it in the report. That at least provides a stack. Symbolicating anything but application frames is still impossible though.
And this isn't even going into esoteric things Android has done over the years just for Chrome like relocation packing:
https://android.googlesource.com/platform/bionic/+/f5e0ba94d...
To this day, I don't understand why both Apple and Google make it so difficult for an application to get access to the stack traces of its own crashes. And no, the reporting built-in to Google Play and iTunes Connect (and Xcode) are not sufficient for large usage apps or companies like mine that have lots of apps with shared SDKs and need to correlate crashes across apps.
Re: Frame pointers vs. DWARF – my verdict
#59IMHO, perf's decision to write whole stacks directly to the disk and unwinding them as a post-process is a really bad design. It wastes disk space, and as the author pointed out, it also has a lot of IO overhead. As an alternative approach, https://github.com/mstange/samply processes data streamed from perf and unwinds it in realtime. The unwinding overhead is surprisingly low: it only takes around 1% of (single) CPU…
If you have framepointers and debug information, it is both high resolution and fast. DWARF is a fallback for not having framepointers.
If you are saying the DWARF information should be processed at the point of use and not copied and processed later, then I concur. But we should also encourage folks to compiled WITH `-fno-omit-frame-pointer` and `-g`
Re: Frame pointers vs. DWARF – my verdict
#60Earlier quoted context omitted.
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 prob…
AFAIK, the optimization undermined the only use case that -fno-omit-frame-pointer actually had on x86_64. Is there a real use case that benefitted from allowing the frame pointer push to wander? Why why why
Having high quality low cost stack straces is important for continuous profiling. ref Knuth.