-
Notifications
You must be signed in to change notification settings - Fork 8
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
Support different panic strategies. #29
Comments
My opinion on this is that Cargo should largely be able to handle all of this transparently without users having to configure anything. My thinking is that users specify a Now obviously like everything else the devil is in the details, so let me be a bit more clear about how I think all this can work.
How's that sound? Does that cover the concerns you were thinking of @ehuss? |
So testing this out a bit today, you can actually get this sort of working today by configuring |
Sorry if this is a dumb question. Are there targets that have a panic strategy of "unwind", but do not want to use libunwind? Such as libunwind does not compile on the target, or the user wants to provide their own panic handler? Alex, you mentioned having a feature to control whether the "panic_unwind" crate is enabled, but I'm hoping to support this without the user specifying If looking at the profile is not sufficient, are there any other options than using features? |
Another question: The |
In general a panic=unwind strategy requires so much compiler support that's basically impossible to implement a custom unwinding panic strategy. In that sense only targets officially supported by rustc (likely tier 1) and shipped with binaries will support unwinding panics, and yeah I think everything there wants to use the libunwind crate and C library in general for unwinding. (MSVC is a bit odd but "eh") I think that we can use the |
The reason I ask is because I have a branch that is switching back to using Looking at the profile is fine if either unwind or abort is what you want, but what if you want neither? Such as the case mentioned above in Should |
Oh ok so if we're passing There's a subtle difference, but we can't look at the profile for The only real solution I can think of for this is to just always compile both If you're in a case where neither is wanted, I think we can automatically detect that based on whether Overall that feels like a lot of custom logic in Cargo for the panic runtimes, which I'm not really overly comfortable with. It's not necessarily the end of the world though? |
Oh, I didn't know about that. I think that does make it easier. And if it is possible to have a fallback for all platforms in I'll try to update my prototype and see how it goes. Thanks! |
So it seems to be working great except for one wrinkle. If you have a project with
I like 3, since it is simple and straightforward, and already works. I think 2 is doable, but I think will be very messy (it will need to create multiple std graphs, know which one to use, etc.), and is also really slow. I don't really know the consequence of 1. Thoughts? |
Definitely (3) in my opinion! I suspect that'll stabilize long before |
…rust_library (#825) Consider a case of a `rust_binary` that depends on a `cc_library` that itself depends on a `rust_library`: ``` . ├── bin.rs ├── BUILD └── lib.rs ``` ```bazel load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library") rust_library( name = "rust_lib", srcs = ["lib.rs"], ) cc_library( name = "cc_lib", srcs = [], deps = [":rust_lib"], ) rust_binary( name = "bin", srcs = ["bin.rs"], deps = [":cc_lib"], ) ``` ```rust // bin.rs fn main() { println!("hi"); } ``` ```rust // lib.rs: empty ``` Running `bazel build //project:bin` runs into several linker errors, which this PR tries to address: - When passing an argument like `-lcrate`, the linker looks for a static library named `libcrate.a`. - the CC link actions get confused by static library names that have multiple dots, e.g., end in "libcrate.rlib.a", so updated the scripts to produce them as "libcrate-rlib.a" instead. - The libraries `panic_abort` and `panic_unwind` are alternatives; attempting to pass both to the linker runs into duplicate symbol errors. Updated the rules to prefer `panic_unwind` if both are available. This is since the standard library by default depends on `panic_unwind`. Note that in platforms where `panic_unwind` is not available, `panic_abort` will be picked. In the future we could add a feature that allows users to pick the panic strategy, aligned with how it will be done in upstream rustc (rust-lang/wg-cargo-std-aware#29). Another thing worth noting is that the way we currently process `.rlib`-s into static libs to pass on to CC rules doesn't quite work when using the current stable `rustc 1.53.0`; it works for the beta `rustc` and beyond: on Linux, a `crate.rlib` is an archive that contains .o files (good) and a Rust metadata file `lib.rmeta` (caution). We symlink `crate.rlib` into `libcrate.a`. The linker generally checks that all members of an archive passed in a `--whole-archive` section are ELF files. The commit rust-lang/rust@c79419a on Jun 4 updated `rustc` so that the produced `lib.rmeta` is an ELF file (previously it was a binary blob), which satisfies the linker checks. This PR does not attempt to address the case where`lib.rmeta` is not an ELF file, hence even with this PR in, trying to run the example with the current stable `rustc 1.53.0` will produce linker errors complaining that an archive member is not recognized, like this one `/usr/bin/ld.gold: error: rust_lib: plugin failed to claim member lib.rmeta at 2480`. With this PR, `bazel build //project:bin` works (with sufficiently recent `rustc`, as described above).
@ehuss Can you recall if anything new came up since this discussion? It seems like all that's needed is to plumb |
I don't think anything new has come up. I think the comments above still capture all the questions that need investigation and experimentation. |
I'd glossed over the trickiness resulting from using |
The current implementation does not support different panic strategies, and is hard-coded for
unwind
. This is a tricky and difficult issue, and there will need to be some investigation and experimentation to figure out all the details. Some things to think about:unwind
andabort
?-C panic=abort
must be passed for thepanic_abort
crate.abort
, need to figure that out.abort
crates, cargo currently rebuilds them withunwind
when built with the libtest harness. Does this mean the entire standard library would need to be built twice? This needs more thought, as it is already subtle and finicky.There is also some hard-coded knowledge in Cargo about building the panic-unwind/abort crates, due to the way the compiler works (just relying on the std feature flags wasn't enough). Alex mentioned a desire to remove this, but I'm not sure how.
The text was updated successfully, but these errors were encountered: