-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More exports #248
Comments
I'm working (in what little time I have) on a stack walker (not focused on actually unwinding the stack until walking it works well) as well: https://github.com/fitzgen/pancakes Perhaps we should work together? IIRC, |
Sounds good! What I have at this point (https://github.com/main--/unwind-rs) can find |
@main-- I factored out the My original goal was to allow iterating over sections within each mapped segment, but that isn't possible with ELF/ So I think instead it makes sense to build a tiny crate on top of When performing actual unwinding, or inspecting the stack from a debugger, we need all the registers. When quickly capturing a stack trace for a profiler, we generally only need a couple of the registers. When unwinding the stack for a panic, we're in the same process as the stack that is being unwound. When implementing a debugger or profiler, it is likely that we are in a different process from the stack being walked, and are presumably using something like https://crates.io/crates/read-process-memory The stack walking / unwinding should be generic / customizable enough to handle all these different scenarios. Also, I strongly typed different kinds of pointers that we encounter, before or after applying the loaders offset, etc: https://github.com/fitzgen/findshlibs/blob/master/src/lib.rs#L51-L72 I find this very helpful for wrapping my head around what kind of pointer I'm dealing with at what times. It might make sense to pull these definitions out into their own crate and use them in Additionally, I have a So that's kind of where I wanted to go / what my plans were. All that said, Oh, one final question: why write assembly rather than use So where do you want to go from here? |
AFAIK I don't actually have a clear understanding of how you're supposed to do this part properly, especially since gimli's Now for all the I can even use the same Long story short: I hate this and I'm really surprised that it works.
What exactly do you mean? Since the encoding allows arbitrary register/frame layout the only optimization I can think of is evaluating registers only lazily, but I kindof doubt that that would make a significant difference.
Stronger types are always good, the only reason
We have the same idea here as that's exactly what I'm doing! I assume you're talking about this function which is the lander glue that jumps to landing pads. I'm just setting all registers because I think that's the cleanest solution, zeroing out the undefined ones.
Maybe? I didn't know about this API, but I also didn't search for anything like that as doing that part in plain asm was just easier (I don't have to worry about what the library function does). One obstacle that comes to my mind right now is how to ensure that everything ... well ... works? What I mean is that any function which returns context data is very hard - if not impossible - to use correctly since that means I'll be walking my own stack frame that I'm changing right now. This is especially tricky when you think about compiler optimizations (most notably inlining). I couldn't really wrap my head around this so I implemented the one reliable mechanism I came up with: Save the calling state and call the unwinder so the frame where it starts unwinding is frozen. It seems like we have two puzzle pieces here: I have a working stacktracer and unwinder while you have some nice abstractions. We could merge if you want to. Obviously the final dream is for So what I may one day end up doing (given enough free time of course) is implementing a complete unwinding+backtracing solution so Rust no longer has to rely on unmaintained upstream libraries for that. An added bonus could be the project I'm working on right now (why I actually created |
Yes, that is what I was getting at :) I ultimately realized that the API I originally imagined was only possible to implement on OSX / Mach-O, and not on Linux / ELF.
Yes. And it is all pretty terribly documented in many far out, disparate locations :( I wonder if inverting how we handle relative pointers makes sense... Return a symbolic form of the pointer, eg Not sure that would actually help at all.
In practice,
A fast path that only handles the above case is a boon for a stack sampling profiler. Implementation wise, I think it is just a different register set struct, that only has the common subset of registers and a cut down version of the unwind routine.
Yeah, I have a similar-ish approach that involves calling a closure + some lifetimes to ensure that you can't return and stomp over everything. https://github.com/fitzgen/pancakes/blob/master/src/x86_64/registers.rs#L108
Sounds good to me :)
Indeed :) So I guess we are left with two immediate questions: |
Some discussion of other people potentially interested in helping out: https://internals.rust-lang.org/t/is-there-any-pure-rust-solution-for-libgcc-s-so-in-libunwind/5998/10 |
Moving it to the |
Right now,
gimli::parser::Pointer
is not exported. Because of that, it's actually not possible to get/use personality functions and lsda pointers.I also needed
gimli::parser::parse_encoded_pointer
to parse the.eh_frame_hdr
for my unwinder, but perhaps that code should just live inside gimli?The text was updated successfully, but these errors were encountered: