diff --git a/examples/trap.wat b/examples/trap.wat new file mode 100644 index 000000000..789073b09 --- /dev/null +++ b/examples/trap.wat @@ -0,0 +1,5 @@ +(module + (func $main (export "main") (result i32) + (i32.div_s (i32.const 0) (i32.const 0)) + ) +) diff --git a/src/sighandler.rs b/src/sighandler.rs index 123487e94..d64bba470 100644 --- a/src/sighandler.rs +++ b/src/sighandler.rs @@ -5,9 +5,11 @@ //! Please read more about this here: https://github.com/CraneStation/wasmtime/issues/15 //! This code is inspired by: https://github.com/pepyakin/wasmtime/commit/625a2b6c0815b21996e111da51b9664feb174622 use nix::sys::signal::{ - sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGFPE, SIGILL, SIGSEGV, + sigaction, Signal, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGFPE, SIGILL, SIGSEGV, }; +static mut SETJMP_BUFFER: [::nix::libc::c_int; 27] = [0; 27]; + pub unsafe fn install_sighandler() { let sa = SigAction::new( SigHandler::Handler(signal_trap_handler), @@ -18,22 +20,29 @@ pub unsafe fn install_sighandler() { sigaction(SIGILL, &sa).unwrap(); sigaction(SIGSEGV, &sa).unwrap(); sigaction(SIGBUS, &sa).unwrap(); - let result = setjmp((&mut SETJMP_BUFFER[..]).as_mut_ptr() as *mut ::nix::libc::c_void); - if result != 0 { - panic!("Signal Error: {}", result); + let signum = setjmp((&mut SETJMP_BUFFER[..]).as_mut_ptr() as *mut ::nix::libc::c_void); + if signum != 0 { + let signal = Signal::from_c_int(signum).unwrap(); + match signal { + SIGFPE => panic!("floating-point exception"), + SIGILL => panic!("illegal instruction"), + SIGSEGV => panic!("segmentation violation"), + SIGBUS => panic!("bus error"), + _ => panic!("signal error: {:?}", signal), + }; } } -static mut SETJMP_BUFFER: [::nix::libc::c_int; 27] = [0; 27]; extern "C" { fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int; fn longjmp(env: *mut ::nix::libc::c_void, val: ::nix::libc::c_int); } -extern "C" fn signal_trap_handler(_: ::nix::libc::c_int) { + +extern "C" fn signal_trap_handler(signum: ::nix::libc::c_int) { unsafe { longjmp( (&mut SETJMP_BUFFER).as_mut_ptr() as *mut ::nix::libc::c_void, - 3, + signum, ); } }