diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
commit | 837b550238aa671a591ccf282dddeab29cadb206 (patch) | |
tree | 914b6b8862bace72bd3245ca184d374b08d8a672 /vendor/cxx/src/unwind.rs | |
parent | Adding debian version 1.70.0+dfsg2-1. (diff) | |
download | rustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz rustc-837b550238aa671a591ccf282dddeab29cadb206.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/cxx/src/unwind.rs')
-rw-r--r-- | vendor/cxx/src/unwind.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/vendor/cxx/src/unwind.rs b/vendor/cxx/src/unwind.rs new file mode 100644 index 000000000..18852da71 --- /dev/null +++ b/vendor/cxx/src/unwind.rs @@ -0,0 +1,39 @@ +#![allow(missing_docs)] + +use core::mem; + +pub fn prevent_unwind<F, R>(label: &'static str, foreign_call: F) -> R +where + F: FnOnce() -> R, +{ + // Goal is to make it impossible to propagate a panic across the C interface + // of an extern "Rust" function, which would be Undefined Behavior. We + // transform such panicks into a deterministic abort instead. When cxx is + // built in an application using panic=abort, this guard object is compiled + // out because its destructor is statically unreachable. When built with + // panic=unwind, an unwind from the foreign call will attempt to drop the + // guard object leading to a double panic, which is defined by Rust to + // abort. In no_std programs, on most platforms the current mechanism for + // this is for core::intrinsics::abort to invoke an invalid instruction. On + // Unix, the process will probably terminate with a signal like SIGABRT, + // SIGILL, SIGTRAP, SIGSEGV or SIGBUS. The precise behaviour is not + // guaranteed and not stable, but is safe. + let guard = Guard { label }; + + let ret = foreign_call(); + + // If we made it here, no uncaught panic occurred during the foreign call. + mem::forget(guard); + ret +} + +struct Guard { + label: &'static str, +} + +impl Drop for Guard { + #[cold] + fn drop(&mut self) { + panic!("panic in ffi function {}, aborting.", self.label); + } +} |