1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
use nix::sys::signal;
pub unsafe fn enable<T, F: FnOnce() -> T>(f: F) -> T {
let buf = vec![0u128; 4096];
let buf = Vec::leak(buf);
let stack = libc::stack_t {
ss_sp: buf.as_ptr() as *mut libc::c_void,
ss_flags: 0,
ss_size: buf.len() * std::mem::size_of::<u128>(),
};
let mut old = libc::stack_t { ss_sp: std::ptr::null_mut(), ss_flags: 0, ss_size: 0 };
let ret = libc::sigaltstack(&stack, &mut old);
assert_eq!(ret, 1, "sigaltstack failed");
let sig_action = signal::SigAction::new(
signal::SigHandler::Handler(handle_sigsegv),
signal::SaFlags::SA_NODEFER | signal::SaFlags::SA_ONSTACK,
signal::SigSet::empty(),
);
signal::sigaction(signal::SIGSEGV, &sig_action).unwrap();
f()
}
extern "C" fn handle_sigsegv(_: i32) {
eprintln!("Stack Overflow:\n{:?}", backtrace::Backtrace::new());
std::process::abort();
}