Skip to content
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 runtime support for unwinding #26569

Merged
merged 4 commits into from
Jun 27, 2015

Conversation

alexcrichton
Copy link
Member

Now that LLVM has been updated, the only remaining roadblock to implementing
unwinding for MSVC is to fill out the runtime support in std::rt::unwind::seh.
This commit does precisely that, fixing up some other bits and pieces along the
way:

  • The seh unwinding module now uses RaiseException to initiate a panic.
  • The rust_try.ll file was rewritten for MSVC (as it's quite different) and is
    located at rust_try_msvc_64.ll, only included on MSVC builds for now.
  • The personality function for all landing pads generated by LLVM is hard-wired
    to __C_specific_handler instead of the standard rust_eh_personality lang
    item. This is required to get LLVM to emit SEH unwinding information instead
    of DWARF unwinding information. This also means that on MSVC the
    rust_eh_personality function is entirely unused (but is defined as it's a
    lang item).

More details about how panicking works on SEH can be found in the
rust_try_msvc_64.ll or seh.rs files, but I'm always open to adding more
comments!

A key aspect of this PR is missing, however, which is that unwinding is still
turned off by default for MSVC
. There is a bug in llvm which
causes optimizations to inline enough landing pads that LLVM chokes. If the
compiler is optimized at -O1 (where inlining isn't enabled) then it can
bootstrap with unwinding enabled, but when optimized at -O2 (inlining is
enabled) then it hits a fatal LLVM error.

This logic applies to all MSVC targets, so instead refactor it into platform.mk
so it can one day apply to 32-bit MSVC.
@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member Author

r? @brson

It may be somewhat premature to land this patch, but I'm curious what others' opinions are. This puts us into a state where unwinding is implemented (e.g. it won't abort the process), but it won't run any destructors as it unwinds a thread (and hence tests will fail).

I've also been discovering some segfaults even with just -C opt-level=1 so there may be some lingering bugs in LLVM that need to be investigated.

Now that LLVM has been updated, the only remaining roadblock to implementing
unwinding for MSVC is to fill out the runtime support in `std::rt::unwind::seh`.
This commit does precisely that, fixing up some other bits and pieces along the
way:

* The `seh` unwinding module now uses `RaiseException` to initiate a panic.
* The `rust_try.ll` file was rewritten for MSVC (as it's quite different) and is
  located at `rust_try_msvc_64.ll`, only included on MSVC builds for now.
* The personality function for all landing pads generated by LLVM is hard-wired
  to `__C_specific_handler` instead of the standard `rust_eh_personality` lang
  item. This is required to get LLVM to emit SEH unwinding information instead
  of DWARF unwinding information. This also means that on MSVC the
  `rust_eh_personality` function is entirely unused (but is defined as it's a
  lang item).

More details about how panicking works on SEH can be found in the
`rust_try_msvc_64.ll` or `seh.rs` files, but I'm always open to adding more
comments!

A key aspect of this PR is missing, however, which is that **unwinding is still
turned off by default for MSVC**. There is a [bug in llvm][llvm-bug] which
causes optimizations to inline enough landing pads that LLVM chokes. If the
compiler is optimized at `-O1` (where inlining isn't enabled) then it can
bootstrap with unwinding enabled, but when optimized at `-O2` (inlining is
enabled) then it hits a fatal LLVM error.

[llvm-bug]: https://llvm.org/bugs/show_bug.cgi?id=23884
If a dylib doesn't actually export any symbols then link.exe won't emit a
`foo.lib` file to link against (as one isn't necessary). Detect this case in the
backend by omitting the `foo.lib` argument to the linker if it doesn't actually
exist.
Makes this test case more robust by using standard libraries to ensure the
binary can be built.
@brson
Copy link
Contributor

brson commented Jun 27, 2015

@bors r+

@bors
Copy link
Contributor

bors commented Jun 27, 2015

📌 Commit 759a7f1 has been approved by brson

@bors
Copy link
Contributor

bors commented Jun 27, 2015

⌛ Testing commit 759a7f1 with merge d3c03d0...

bors added a commit that referenced this pull request Jun 27, 2015
Now that LLVM has been updated, the only remaining roadblock to implementing
unwinding for MSVC is to fill out the runtime support in `std::rt::unwind::seh`.
This commit does precisely that, fixing up some other bits and pieces along the
way:

* The `seh` unwinding module now uses `RaiseException` to initiate a panic.
* The `rust_try.ll` file was rewritten for MSVC (as it's quite different) and is
  located at `rust_try_msvc_64.ll`, only included on MSVC builds for now.
* The personality function for all landing pads generated by LLVM is hard-wired
  to `__C_specific_handler` instead of the standard `rust_eh_personality` lang
  item. This is required to get LLVM to emit SEH unwinding information instead
  of DWARF unwinding information. This also means that on MSVC the
  `rust_eh_personality` function is entirely unused (but is defined as it's a
  lang item).

More details about how panicking works on SEH can be found in the
`rust_try_msvc_64.ll` or `seh.rs` files, but I'm always open to adding more
comments!

A key aspect of this PR is missing, however, which is that **unwinding is still
turned off by default for MSVC**. There is a [bug in llvm][llvm-bug] which
causes optimizations to inline enough landing pads that LLVM chokes. If the
compiler is optimized at `-O1` (where inlining isn't enabled) then it can
bootstrap with unwinding enabled, but when optimized at `-O2` (inlining is
enabled) then it hits a fatal LLVM error.

[llvm-bug]: https://llvm.org/bugs/show_bug.cgi?id=23884
@bors bors merged commit 759a7f1 into rust-lang:master Jun 27, 2015
bors added a commit that referenced this pull request Jun 28, 2015
This series of commits (currently rebased on #26569 to avoid conflicts) adds support for the standard library to run on Windows XP. The main motivation behind this PR is that to enable any Rust code in Firefox we need to support Windows XP.

This PR doesn't yet intend to be a move to make Windows XP an officially supported platform, but instead simply get Rust code running on it. APIs like condition variables and RWLocks will immediately panic currently on XP, and it's unclear if that story wants to change much. Additionally, we may bind APIs like IOCP which aren't available on XP and would be *very* difficult to provide a fallback implementation. Essentially this PR enables running Rust on XP, but you still have to be careful to avoid non-XP portions of the standard library.

The major components of this PR are:

* Support for a new `i686-pc-windows-msvc` triple. This primarily involves a lot of build system hackery, but there are also a number of floating point functions which had to get switched up a bit.
* All APIs not available on Windows are now accessed through our dynamic-detection mechanism
* Mutexes on Windows were rewritten to use SRWLOCK as an optimization but can fall back to CRITICAL_SECTION.
@alexcrichton alexcrichton deleted the msvc-llvm-update branch June 28, 2015 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants