Unwinding the Stack the Hard Way
lesenechal.fr
lesenechal.fr
Of course it won't work in edge cases like handwritten Asm that uses the stack in more clever ways, but when you're dealing with compiler output, it'll be fine. No need for all this complexity, and works in almost all cases.
Windows: VirtualQuery()
Mac: vm_region()
Your own OS (like this article): you should know.
If it's a graph of potential stacks, though, wouldn't you eventually find the one that unwinds, if one exists?
Since we do post-hoc stack walking our ability to actually look at the assembly is limited. In most cases where we have no CFI we also do not have the binary to begin with, so we're in random memory land.
I'm not familiar with Rust, but if I'm reading it correctly, you're not doing back-disassembly and only checking if an address on the stack is in a code region, which certainly won't work well.
we also do not have the binary to begin with
Your "minidumps" only contain the stack?
I linked you to it elsewhere in this thread. Sentry is using a rust implementation of the stack walker.
https://github.com/google/breakpad/blob/main/docs/stack_walk...
Also see recent discussion here:
I dug around in that code a little, and although it contains a disassembler, it's not being used for inspecting the call chain. All it does is check that the address appears to be inside a code section.
https://github.com/google/breakpad/blob/main/src/processor/s...
Since then I gave a short (15 min) talk about producing and understanding flame graphs: http://oirase.annexia.org/tmp/2023-03-08-flamegraphs.mp4
My comment on that article still stands: https://news.ycombinator.com/item?id=34660474
tl;dr: don't make code generation worse for everyone else just to appease your one tiny use-case; fix your goddamn tools instead.
- ARM frame pointer handling is more compact (relative to the non-frame pointer code) than that on RISC-V.
- ARM code does less frame pointer handling.
The first might be true because ARM has the stmdb instruction which (https://developer.arm.com/documentation/ddi0406/b/Applicatio...) stores multiple registers to consecutive memory locations using an address from a base register. The consecutive memory locations end just below this address, and the address of the first of those locations can optionally be written back to the base register.
So, code can save registers on the stack _and_ decrease the stack pointer in a single instruction.
The second might be true because, of the compilers/compiler settings used for those measurements the ARM one did more aggressive function inlining.
We really wish frame pointers were always present, but here we are.
[1] https://www.polarsignals.com/blog/posts/2022/11/29/profiling...
The downside - it required many patches to LLVM's libunwind, and not all of them are accepted yet: https://bugs.llvm.org/show_bug.cgi?id=48186
ClickHouse source code: https://github.com/ClickHouse/ClickHouse
I recommend the author not examine JVM null pointer handling too closely then.
Also wanted to mention your comment was [dead], had to vouch for it to resurrect it.
[1] ISO/IEC 9899:2011 §6.5.3.2
[0] https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Optimize-Option....
P.S. Seems like your account is shadowbanned. Might want to contact dang: hn@ycombinator.com if you plan on posting more.
[1] https://lwn.net/Articles/342330/
PS: I took action by contacting Dang about the shadowban; thank you for warning me, I was wondering why I felt like a ghost.
From what I recall (it's been ~ 5 years), at least on OpenJ9, the potential SIGSEGV's for null references occurred in code generated by our JIT compiler, or in hand-rolled assembly, and not in code generated by any C translation unit. This may well not satisfy the standard, but honestly, at that point, I'm not sure any FFI-linked code will.
If you find this distinction insufficient, and still require the use of a JVM, if my memory serves correctly, -Xrs on OpenJ9 will avoid using those trap handlers. I don't believe this is true of Hotspot.
if err := nil { return err }