summaryrefslogtreecommitdiffstats
path: root/vendor/cxx/src/unwind.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
commit837b550238aa671a591ccf282dddeab29cadb206 (patch)
tree914b6b8862bace72bd3245ca184d374b08d8a672 /vendor/cxx/src/unwind.rs
parentAdding debian version 1.70.0+dfsg2-1. (diff)
downloadrustc-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.rs39
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);
+ }
+}