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

Still cannot build project with 'panic = abort' #2738

Closed
alexbool opened this issue May 24, 2016 · 15 comments
Closed

Still cannot build project with 'panic = abort' #2738

alexbool opened this issue May 24, 2016 · 15 comments

Comments

@alexbool
Copy link

This time compiler plugins seem to be the culprit

alexbool@alexbool-osx ~/D/I/nounwind> cat Cargo.toml 
[package]
name = "nounwind"
version = "0.1.0"
authors = ["Alexander Bulaev <[email protected]>"]

[dependencies]
quasi_macros = "*"

[profile.release]
panic = "abort"

alexbool@alexbool-osx ~/D/I/nounwind> cat src/main.rs 
extern crate quasi_macros;

fn main() {
}

alexbool@alexbool-osx ~/D/I/nounwind> cargo build --release
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling aster v0.16.0
   Compiling quasi_codegen v0.10.0
   Compiling quasi_macros v0.10.0
error: the linked panic runtime `panic_unwind` is not compiled with this crate's panic strategy `abort`
error: aborting due to previous error
error: Could not compile `quasi_macros`.

To learn more, run the command again with --verbose.

This time adding

[profile.dev]
panic = "abort"

doesn't help

Meta:

alexbool@alexbool-osx ~/D/I/nounwind> rustc -vV
rustc 1.10.0-nightly (57ef01513 2016-05-23)
binary: rustc
commit-hash: 57ef015132ec09345b88d2ec20a9d9809b5d3dfc
commit-date: 2016-05-23
host: x86_64-apple-darwin
release: 1.10.0-nightly
alexbool@alexbool-osx ~/D/I/nounwind> cargo -vV
cargo 0.11.0-nightly (ca743f3 2016-05-23)
@alexcrichton
Copy link
Member

Thanks for the report! And yes, hm, indeed, this is a problem!

I'll have to noodle on a way to fix this, unfortunately it probably won't be trivial

@mitsuhiko
Copy link
Contributor

@alexcrichton if it's hard to fix, maybe it's easier to detect that problem and tell the user why it's broken and link to this here. That was surprisingly hard to google for and it wastes quite a bit of time.

@alexcrichton
Copy link
Member

Hm let me elaborate on what I'm thinking for this:

  • You can't link a crate compiled with panic=abort to a dylib compiled with panic=unwind
  • Plugins link to libsyntax/librustc/etc, all of which are compiled with panic=unwind
  • As a result, all plugin crates must be compiled with panic=unwind
  • This gets tricky, because dependencies of plugins must also be compiled with panic=unwind
  • It may be the case that a dependency is shared between the main application (panic=abort) and also a plugin (panic=unwind). In this scenario we don't recompile the crate and just call the compiler once.

My idea for a solution here is to just have a "panic" flag which is set for plugins and all of their dependencies, so even though panic=abort is requested all the deps are compiled with panic=unwind. That means you may link unwinding code into the main app if you're not cross compiling, but that should still all link just fine in the end as it's designed for panic=unwind crates to link to panic=abort ones anyway.

@mitsuhiko it's probably not really any harder to fix than it is to detect, so just need to find some time to implement this.

@alexbool
Copy link
Author

Any good news on this? Basically it blocks panic=abort if you use nightly compiler with serde plugin, which I believe is a frequent use case

alexcrichton added a commit to alexcrichton/cargo that referenced this issue Aug 4, 2016
bors added a commit that referenced this issue Aug 7, 2016
Fix panic=abort when compiling with plugins

Closes #2738
@bors bors closed this as completed in #2954 Aug 7, 2016
@UserAB1236872
Copy link

UserAB1236872 commented Oct 4, 2016

Seems to still be an issue despite the merge/close:

Cargo.toml:

[package]
name = "panic_test"
version = "0.1.0"

[profile.release]
panic = "abort"

[dependencies]
lodepng = "0.11"

The main.rs is just a Hello World program. It yields the same error (error: the linked panic runtime panic_unwind is not compiled with this crate's panic strategy abort) when compiled with cargo build --release. Additional testing with profiles such as dev yield the same problem.

Fails on both 1.12 stable and nightly (144af3e97 2016-10-02).

@alexcrichton
Copy link
Member

@Jragonmiris ah unfortunately that's a bad error message but it's because of crate-type = ["dylib", "rlib"] in the c_vec crate. This causes Cargo to pass -C prefer-dynamic which links to the dylib that we ship which is compiled against panic_unwind, meaning the abort mode is indeed invalid (this error is coming from the compiler).

The fix here would be to remove "dylib" from the c_vec crate.

@AaronFriel
Copy link

I have a simple project whose only direct dependency is clap, and it's failing to compile with panic = "abort" because of this issue. I can hardly say more than that this seems the pluggable panic behavior is a flawed feature if users must alter their dependencies, or dependency's dependencies, and so on.

@alexcrichton
Copy link
Member

@AaronFriel do you have a Cargo.toml I can reproduce with? A simple one with clap = "*" doesn't reproduce that behavior. Maybe clap changed over time though?

@AaronFriel
Copy link

Would it affect anything that I'm building on Windows? Here's my cargo.toml:

[package]
name = "flairs"
version = "0.1.0"
authors = ["Aaron Friel <[email protected]>"]

[dependencies]
clap="^2.13.0"

@alexcrichton
Copy link
Member

Hm even then I wasn't able to reproduce. Could you gist a full build of rustc -vV, cargo -V, and cargo build -v ?

@AaronFriel
Copy link

I have reduced the problem to being unable to cargo bench, cargo build works fine if I add panic = "abort" to the appropriate profile settings.

@AaronFriel
Copy link

@alexcrichton
Copy link
Member

@AaronFriel ah yeah unfortunately cargo bench with panic="abort" doesn't work today, but that's definitely a bug in Cargo (e.g. cargo test works). Can you open a separate issue about that?

@AaronFriel
Copy link

Sure! I created issue #3166

@alexcrichton
Copy link
Member

Thanks!

PaulGrandperrin added a commit to rust-fuzz/honggfuzz-rs that referenced this issue Apr 23, 2018
**Context:**

For the fuzzer to be able to "understand" that something went wrong,
like a panic, the process must terminate in an abnormal fashion.

The default panic hook will unwind the stack, run destructors,
optionally print a backtrace and exit with code 101. The fuzzer will
not be able to "understand" that something wwnt particuliarly wrong.

One way to stop a process in a way that the fuzzer understands as
abnormal is to call `std::process::abort()`.

**Possible solutions:**

- build with "-C panic=abort":
  incompatible with compiler plugins
  rust-lang/cargo#2738 (comment)
  rust-fuzz/afl.rs#120
- use `panic::catch_unwind()` to catch unwinding stacks and call `std::process::abort()`:
  all kind of bugs will then unwind their stack up to the code calling this function
  and therefore render different bugs indistinguishable from the fuzzer point of view.
- use a custom panic hook and call `std::process::abort()` here.

**Implemented solution**
We implemented both solution 2 and 3.
Solution 3 has no drawbacks that I know of, but could potentially be
missed if the fuzzed code modifies the panic hook. In this case, we fall
back to solution 2 as a last resort.
PaulGrandperrin added a commit to rust-fuzz/honggfuzz-rs that referenced this issue Apr 23, 2018
**Context:**

For the fuzzer to be able to "understand" that something went wrong,
like a panic, the process must terminate in an abnormal fashion.

The default panic hook will unwind the stack, run destructors,
optionally print a backtrace and exit with code 101. The fuzzer will
not be able to "understand" that something went particuliarly wrong.

One way to stop a process in a way that the fuzzer understands as
abnormal is to call `std::process::abort()`.

**Possible solutions:**

- build with "-C panic=abort":
  incompatible with compiler plugins
  rust-lang/cargo#2738 (comment)
  rust-fuzz/afl.rs#120
- use `panic::catch_unwind()` to catch unwinding stacks and call `std::process::abort()`:
  all kind of bugs will then unwind their stack up to the code calling this function
  and therefore render different bugs indistinguishable from the fuzzer's point of view.
- use a custom panic hook and call `std::process::abort()` here.

**Implemented solution**

We implemented both solution 2 and 3.
Solution 3 has no drawbacks that I know of, but could potentially be
missed if the fuzzed code modifies the panic hook. In this case, we fall
back to solution 2 as a last resort.
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

No branches or pull requests

5 participants