Stream: project-ffi-unwind

Topic: Is unwinding through extern C UB?


view this post on Zulip Elichai Turkel (Mar 12 2021 at 22:49):

I read the RFC again and I'm not sure I understand exactly,
Is this UB or converted to abort?

#[no_mangle]
pub unsafe extern "C" fn call_this_from_c() {
    panic!("message")
}

(specifically in my case it's rust->c->rust and the last/inner rust is panicking).
I thought it was abort but now that https://github.com/rust-lang/rust/pull/76570 is merged we're getting sefaults: https://github.com/rust-bitcoin/rust-secp256k1/pull/288
((signal: 4, SIGILL: illegal instruction))

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 22:56):

@katelyn martin is this part of the behavior change behind the feature flag?

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:00):

SIGILL is not a segfault, though; I believe it's considered a "valid" means of causing an abort. I think I remember SIGILL intentionally being our means of aborting-on-panic, but I can't remember where I heard this.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:03):

This is crate documentation, not rustc documentation, but it seems to confirm that: https://docs.rs/panic-abort/0.3.2/panic_abort/

On hosted applications (applications running under an OS), the trap instruction usually terminates the whole process with an exit code that corresponds to SIGILL unless a signal handler that handles this particular signal was registered...

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:05):

Ah, okay, here's something a little more definite: https://github.com/rust-lang/rust/issues/52633

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:07):

rustc lowers abort to llvm.trap, an intrinsic that is platform-specific: https://llvm.org/docs/LangRef.html#llvm-trap-intrinsic

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:07):

So, yes, what you're seeing is an abort.

view this post on Zulip Elichai Turkel (Mar 12 2021 at 23:11):

Oh that's a weird abort but cool.
(why doest rust call libc::abort or prints before aborting here?)

So is this an intentional change even though c-unwind is feature gated?

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:15):

Printing when you haven't asked for printing would be...irregular, in a low-level language :laughing:

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:16):

I was in no way involved w/ implementing rustc, but I would guess the reason for not using libc is that it's not available on all platforms; deferring to the backend (LLVM) for an intrinsic seems more consistent.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:16):

(Also note that abort should only happen in exceptional cases; it's not a "happy path" way to halt a program.)

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:16):

And, yes, this is an intentional change (it meets the RFC spec).

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:17):

Looking over the code change itself, the abort behavior is untouched; I expect you would get the same exit code for any panic if you compiled with panic=abort.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:18):

If you want the old behavior from extern "C", you should definitely opt into the feature gate.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:18):

(or not use nightly)

view this post on Zulip Elichai Turkel (Mar 12 2021 at 23:22):

BatmanAoD (Kyle Strand) said:

Printing when you haven't asked for printing would be...irregular, in a low-level language :laughing:

Doesn't C's abort print? maybe I'm misremembering

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:26):

libc? It may.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:26):

I'm not sure either.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 12 2021 at 23:31):

It may also depend on the implementation of libc.

view this post on Zulip nagisa (Mar 12 2021 at 23:44):

https://github.com/rust-lang/rust/issues/47932 related I guess.

view this post on Zulip nagisa (Mar 12 2021 at 23:44):

also less relatedly https://github.com/rust-lang/rust/issues/81895

view this post on Zulip katelyn martin (Mar 17 2021 at 21:44):

Hello! Apologies for the delay. To answer the question posed at the beginning of the thread, an unwinding operation crossing an extern "C" boundary prior to this RFC was considered UB. Today, that should now abort.

is this part of the behavior change behind the feature flag?

@BatmanAoD (Kyle Strand) Alas. I don't believe that is the case. Because that behavior was previously undefined however, would a patch to preserve that be worthwhile? I'm _inclined_ to guess not, but I have a bit less experience with the day-to-day of rustc maintenance.

view this post on Zulip bjorn3 (Mar 17 2021 at 22:30):

I think the old behavior should be preserved for as long as extern "C-unwind" is unstable.

view this post on Zulip BatmanAoD (Kyle Strand) (Mar 17 2021 at 23:42):

I think I agree with that. I was hoping it wouldn't make a difference because we could stabilize near-immediately, but I think stabilization must be blocked by the issue brought up in the "UB testcase" discussion.


Last updated: Jan 26 2022 at 08:02 UTC