Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

When is a panic on a Rust FFI boundary Undefined Behavior?

The rustnomicon contains the following example:

#[no_mangle]
extern "C" fn assert_nonzero(input: u32) {
    assert!(input != 0)
}

If assert_nonzero is called with the argument 0, the runtime is guaranteed to (safely) abort the process, whether or not compiled with panic=abort.


The Rust Reference on the other hand claims that:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Behavior considered undefined: […] Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI.


These two statements seem contradictory to me. assert_nonzero has the C ABI, but unwinds from a Rust panic. So is that guaranteed to (safely) abort, or UB? It can’t be both.

Chayim Friedman kindly suggested on another question that this is indeed UB.

So is the Rustnomicon simply outdated, or am I misunderstanding something?

More generally: Exactly when is a Rust panic crossing an FFI boundary considered Undefined Behavior?

>Solution :

From the RFC for -unwind ABIs:

Changes to the behavior of existing ABI strings

Prior to this RFC, any unwinding operation that crossed an extern "C" boundary, either from a panic! "escaping" from a Rust function
defined with extern "C" or by entering Rust from another language
via an entrypoint declared with extern "C", caused undefined
behavior.

This RFC retains most of that undefined behavior, with one exception:
with the panic=unwind runtime, panic! will cause an abort if it
would otherwise "escape" from a function defined with extern "C".

This change will be applied to all ABI strings other than "Rust",
such as "system".

So it appears that this used to be UB, but after this RFC was accepted, this is no longer UB and guaranteed to abort.

I don’t know if we can say that the reference is outdated, since we can say that we just don’t unwind (but abort) on panics from extern "C" Rust functions.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading