-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
MSVC: Implement 32-bit Unwinding #25869
Comments
LLVM has been upgrade, this is now blocked on https://llvm.org/bugs/show_bug.cgi?id=23884 I believe. |
A question about this: Last time we talked, Alex mentioned that this was blocked on getting SEH-compatible unwinding to work on 32-bit Windows. According to Microsoft's documentation, in MSVC C++ mode, they recommend not to use the SEH-compatible unwinding for reasons of correctness and performance. See https://msdn.microsoft.com/en-us/library/1deeycx5.aspx. Which MSVC /EH option is most similar to Rust's (proposed) handling of unwinding? And, is SEH-compatible unwinding really necessary? |
@briansmith That article is recommending to not use a flag which would let C++ exceptions catch arbitrary SEH exceptions, things like stack overflow and divide by zero. Internally all the exceptions and unwinding in the msvc world are using SEH. Basically you're confused between the class of exceptions referred to as SEH exceptions and SEH as the unwinding/exception mechanism. |
Ah thanks for the ping @briansmith, I should give a status update on this. Currently unwinding on 64-bit MSVC is fully implemented using DWARF side tables like the GNU triple uses and we implement the necessary runtime support to parse these side tables. Unwinding on 32-bit MSVC is unimplemented, however. I have not investigated too closely what it would mean to implement DWARF unwinding for 32-bit like we have for 64-bit (I believe @vadimcn knows more about this than I do). My current idea for implementing 32-bit is to wait for LLVM's exception handling intrinsics to be fully implemented. I'm under the impression they're relatively experimental for now and are unlikely to work for us (but I haven't checked in awhile). Once those exist we can switch to those for 32 and 64 bit MSVC, tweak some runtime support, and in theory "Just Work". In any case, however, unwinding from C++ to Rust is undefined behavior no matter what happens (and vice versa), so exceptions/panics must always be caught at FFI boundaries. In that sense SEH compatible unwinding isn't necessary, but we need a solution for 32-bit still. |
Right. Maybe I misunderstood, but my impression is that people felt that resolving this was blocked on SEH-compatible unwinding. My point is that a lot of people targetting -msvc don't need or want SEH-compatible unwinding, especially if it has negative perf/size implications. That is, if this bug were resolved with (only) a SEH-compatible unwinder, then there should be a follow-up issue to track more efficient unwinding. I believe the LLVM work is intended to support mixing MSVC-compiled C++ code with clang-compiled C++ code with exceptions that traverse stacks of code implemented with each compiler; i.e. 100% interop with the MSVC C++ ABI. That's quite a different problem from what Rust needs, AFAICT. AFAICT, the requirements for the unwinder are just that implementations of |
@briansmith: The code that unwinds stack using DWARF frame info lives in libgcc. Furthermore, because of the way module registration with the unwinder is implemented, we must link to the dynamic version of libgcc. I am guessing that @alexcrichton did not want to have this dependency in *-pc-windows-msvc executables. |
Yes, from my perspective. 32-bit Windows is the most important target in that it is the target that covers the most users. In particular, 32-bit Windows apps work on 64-bit Windows AND 32-bit Windows. From the end-user-of-Rust perspective, it seems very risky to wait for LLVM to eventually fix this, especially when Alex said that LLVM's implementation is likely to not even work for Rust even when it is finished at some unknown point in time in the future. That said, I'm biased because I've invested a lot of time to create infrastructure software in Rust, and in order to convince people to use my software, I have to convince them that Rust isn't super risky, and this is one of the issues that people have mentioned as a concern. |
Ah to be clear I just mean that LLVM's implementation right this red hot second is unlikely to work (e.g. the WIP variant), I expect it is certainly aimed at working quite well in the very near future, e.g. the next 3.8 release most likely. I haven't checked up on the progress in awhile though, but if there's good pressure to get this working robustly on 32-bit MSVC I can certainly shift some time into investigating! |
Seem you deleted the WIP branch https://github.com/alexcrichton/rust/tree/msvc-llvm-update That was for 64bit, right? (Maybe delete or What do you think the timeline is on getting unwinding support for 32bit? This year? Next year? I agree with @briansmith that Windows 32bit is the platform with the biggest userbase period. I'm working on porting to Rust an existing Windows app where file size matters. So need to use 32 bit to reach both 32 and 64 bit Windows users. No stack unwinding doesn't make it impossible to write the app, but it makes it harder to debug and much harder to convince people that this is a good idea to do. I'm not compiler hacker, but is there anything I can do to help? |
@kosta, is there a particular reason you can't use the i686-pc-windows-gnu flavor? It has full support for unwinding. |
My current thoughts are to hold off until LLVM 3.8 and then try again to use the native MSVC unwinding intrinsics, but that's mostly because I don't know of the status of that implementation in LLVM. If it's ready now then we'd be fine just updating the submodule we've got and using it. @vadimcn has a point though, does the gnu 32-bit triple not work for you? If you're compiling and linking with an MSVC-compiled native library it may not work out well but otherwise it should work! |
I'm currently re-evaluating using gcc and will reply once I'm done... |
The corresponding LLVM bug has been closed now, and it may be the case that LLVM's support for SEH and such is much better now than it was before, so we can perhaps try to start transitioning towards that soon! |
These commits perform a few high-level changes with the goal of enabling i686 MSVC unwinding: * LLVM is upgraded to pick up the new exception handling instructions and intrinsics for MSVC. This puts us somewhere along the 3.8 branch, but we should still be compatible with LLVM 3.7 for non-MSVC targets. * All unwinding for MSVC targets (both 32 and 64-bit) are implemented in terms of this new LLVM support. I would like to also extend this to Windows GNU targets to drop the runtime dependencies we have on MinGW, but I'd like to land this first. * Some tests were fixed up for i686 MSVC here and there where necessary. The full test suite should be passing now for that target. In terms of landing this I plan to have this go through first, then verify that i686 MSVC works, then I'll enable `make check` on the bots for that target instead of just `make` as-is today. Closes #25869
Updated report
Original Report
Right now the MSVC target turns all calls to
panic!
into a process-wide abort as unwinding is not implemented.WIP branch:
https://github.com/alexcrichton/rust/tree/msvc-llvm-update(now merged)The text was updated successfully, but these errors were encountered: