Skip to content

Commit 52614de

Browse files
committed
Added signal handler to handle WebAssembly traps properly
Please read more about this here: bytecodealliance/wasmtime#15 Code inspired by: pepyakin/wasmtime@625a2b6
1 parent ac23b91 commit 52614de

File tree

5 files changed

+67
-0
lines changed

5 files changed

+67
-0
lines changed

Cargo.lock

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ spin = "0.4.10"
4242
log = "0.4.5"
4343
target-lexicon = { version = "0.0.3", default-features = false }
4444
libc = "0.2"
45+
nix = "0.11"
4546

4647
[build-dependencies]
4748
wabt = "0.6.0"

src/macros.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
#[macro_export]
55
macro_rules! get_instance_function {
66
($instance:expr, $func_index:expr) => {{
7+
use crate::sighandler::install_sighandler;
78
use std::mem;
9+
10+
unsafe {
11+
install_sighandler();
12+
};
813
let func_addr = $instance.get_function_pointer($func_index);
914
unsafe { mem::transmute(func_addr) }
1015
}};

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern crate cranelift_wasm;
1212
extern crate wabt;
1313
#[macro_use]
1414
extern crate target_lexicon;
15+
extern crate nix;
1516
extern crate spin;
1617

1718
// use std::alloc::System;
@@ -37,6 +38,7 @@ use wabt::wat2wasm;
3738
mod macros;
3839
pub mod common;
3940
pub mod integrations;
41+
pub mod sighandler;
4042
#[cfg(test)]
4143
mod spectests;
4244
pub mod webassembly;

src/sighandler.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! We install signal handlers to handle WebAssembly traps within
2+
//! our Rust code. Otherwise we will have errors that stop the Rust process
3+
//! such as `process didn't exit successfully: ... (signal: 8, SIGFPE: erroneous arithmetic operation)`
4+
//!
5+
//! Please read more about this here: https://github.com/CraneStation/wasmtime/issues/15
6+
//! This code is inspired by: https://github.com/pepyakin/wasmtime/commit/625a2b6c0815b21996e111da51b9664feb174622
7+
use nix::sys::signal::{
8+
sigaction, SaFlags, SigAction, SigHandler, SigSet, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
9+
};
10+
11+
pub unsafe fn install_sighandler() {
12+
let sa = SigAction::new(
13+
SigHandler::Handler(signal_trap_handler),
14+
SaFlags::empty(),
15+
SigSet::empty(),
16+
);
17+
sigaction(SIGFPE, &sa).unwrap();
18+
sigaction(SIGILL, &sa).unwrap();
19+
sigaction(SIGSEGV, &sa).unwrap();
20+
sigaction(SIGBUS, &sa).unwrap();
21+
let result = setjmp((&mut setjmp_buffer[..]).as_mut_ptr() as *mut ::nix::libc::c_void);
22+
if result != 0 {
23+
panic!("Signal Error: {}", result);
24+
}
25+
}
26+
27+
static mut setjmp_buffer: [::nix::libc::c_int; 27] = [0; 27];
28+
extern "C" {
29+
fn setjmp(env: *mut ::nix::libc::c_void) -> ::nix::libc::c_int;
30+
fn longjmp(env: *mut ::nix::libc::c_void, val: ::nix::libc::c_int);
31+
}
32+
extern "C" fn signal_trap_handler(_: ::nix::libc::c_int) {
33+
unsafe {
34+
longjmp(
35+
(&mut setjmp_buffer).as_mut_ptr() as *mut ::nix::libc::c_void,
36+
3,
37+
);
38+
}
39+
}

0 commit comments

Comments
 (0)