| use std::io::{self, Write}; |
| use std::panic::{self, AssertUnwindSafe}; |
| use std::process; |
| |
| pub fn catch_unwind<F, R>(label: &'static str, foreign_call: F) -> R |
| where |
| F: FnOnce() -> R, |
| { |
| // Regarding the AssertUnwindSafe: we immediately abort on panic so it |
| // doesn't matter whether the types involved are unwind-safe. The UnwindSafe |
| // bound on catch_unwind is about ensuring nothing is in a broken state if |
| // your program plans to continue after the panic. |
| match panic::catch_unwind(AssertUnwindSafe(foreign_call)) { |
| Ok(ret) => ret, |
| Err(_) => abort(label), |
| } |
| } |
| |
| #[cold] |
| fn abort(label: &'static str) -> ! { |
| let mut stderr = io::stderr(); |
| let _ = writeln!(stderr, "Error: panic in ffi function {}, aborting.", label); |
| process::abort(); |
| } |