>>107387152
#![feature(thread_local)]
use std::ptr;
use cee_scape::{siglongjmp, SigJmpBufFields};
use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal};
enum FuncResult {
Success(u8),
SegFault,
}
unsafe fn try_dangerous_func(func: unsafe fn() -> u8) -> FuncResult {
#[thread_local]
static mut JUMP_BUF: *const SigJmpBufFields = ptr::null_mut();
extern "C" fn handler(_: libc::c_int) { unsafe {
println!("In handler!");
if let Some(env) = JUMP_BUF.as_ref() {
JUMP_BUF = ptr::null();
siglongjmp(env, -1)
}
}}
let result = cee_scape::call_with_sigsetjmp(true, |env| unsafe {
JUMP_BUF = env;
sigaction(Signal::SIGSEGV, &SigAction::new(SigHandler::Handler(handler), SaFlags::empty(), SigSet::empty())).unwrap();
let result = func();
JUMP_BUF = ptr::null();
result as _
});
if result < 0 {
FuncResult::SegFault
} else {
FuncResult::Success(result as u8)
}
}
fn ok_func() -> u8 {
1 + 2
}
unsafe fn segfault_func() -> u8 {
unsafe { ptr::null_mut::<u8>().read() }
}
fn main() { unsafe {
match try_dangerous_func(ok_func) {
FuncResult::Success(result) => println!("function ran successfully: {result}"),
FuncResult::SegFault => println!("caught segfault"),
}
match try_dangerous_func(segfault_func) {
FuncResult::Success(result) => println!("function ran successfully: {result}"),
FuncResult::SegFault => println!("caught segfault"),
}
}}
But what's the point of this exercise if there is no way to reliably measure its performance? Wasn't your point all about Rust being slow? Because now it looks like you are trying to find the most esoteric usecase imaginable instead of doing anything performance critical.