I am writing a library involving FFI (with C), which needs to pass to a foreign function a pointer to a Rust function, which may panic, and must ergo catch the panic at the boundary, jump over the foreign stack frame, and resume unwinding — if unwinding is enabled. I want this library to be useful either sans runtime, or with it.
Options which come to mind:
#[cfg] by panic strategy — to my knowledge no such cfg parametre is
define __rust_start_panic and __rust_maybe_catch_panic with weak linkage — no idea whether this would even work, and likely highly unstable
What is the reliable method to catch panic iff unwinding enabled?
For the curious: the library is of a text screen and scrollback buffer, e.g. for a terminal emulator, which may be useful for terminal emulators in both user- and kernel-space, thus my concern about the runtime.
I don't fully understand. You can use catch_unwind both with the abort and the panicking runtime. It will just never catch and return an error with the abort one.
You pass the returned result over the FFI boundary and back and continue panicking if the result holds a panic value. I haven't got a compiler at hand, currently, but in case of the abort runtime, panicking::try (the internal implementation of catch_unwind) should pretty much optimise to Ok(closure.call()).
I usually define a macro that'll automatically wrap a function in catch_unwind(). There's no need to play around with #[cfg] or linkage.
I also maintain a pretty detailed FFI guide that may be useful to you. I believe there's a section regarding exception safety (preventing panics) under "error handling".
I mostly care about your cases 1 and 2, at least for now. My concern is, if whether my library catches panics is a function of a feature flag, the user could cause UB with no unsafe blocks, merely by toggling the flag.