Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/disable_host_trap_handlers.rs
1685 views
1
//! A standalone test to assert that Wasmtime can operate in "no signal handlers
2
//! mode"
3
//!
4
//! This is a test for `Config::signals_based_traps(false)` which resides in its
5
//! own binary to assert properties about signal handlers that Wasmtime uses.
6
//! Due to the global nature of signals no other tests can be in this binary.
7
//! This will ensure that various trapping scenarios all work and additionally
8
//! signal handlers are not registered.
9
10
use anyhow::Result;
11
use wasmtime::{Config, Engine, Instance, Module, Store, Trap};
12
13
#[test]
14
#[cfg_attr(miri, ignore)]
15
fn no_host_trap_handlers() -> Result<()> {
16
let mut config = Config::new();
17
config.signals_based_traps(false);
18
let engine = Engine::new(&config)?;
19
let module = Module::new(
20
&engine,
21
r#"
22
(module
23
(memory 1)
24
25
(func (export "load") (param i32) (result i32)
26
(i32.load (local.get 0)))
27
28
(func (export "div") (param i32 i32) (result i32)
29
(i32.div_s (local.get 0) (local.get 1)))
30
31
(func (export "unreachable") unreachable)
32
(func $oflow (export "overflow") call $oflow)
33
)
34
"#,
35
)?;
36
37
let mut store = Store::new(&engine, ());
38
let instance = Instance::new(&mut store, &module, &[])?;
39
let load = instance.get_typed_func::<i32, i32>(&mut store, "load")?;
40
let div = instance.get_typed_func::<(i32, i32), i32>(&mut store, "div")?;
41
let unreachable = instance.get_typed_func::<(), ()>(&mut store, "unreachable")?;
42
let overflow = instance.get_typed_func::<(), ()>(&mut store, "overflow")?;
43
44
let trap = load
45
.call(&mut store, 1 << 20)
46
.unwrap_err()
47
.downcast::<Trap>()?;
48
assert_eq!(trap, Trap::MemoryOutOfBounds);
49
50
let trap = div
51
.call(&mut store, (1, 0))
52
.unwrap_err()
53
.downcast::<Trap>()?;
54
assert_eq!(trap, Trap::IntegerDivisionByZero);
55
56
let trap = unreachable
57
.call(&mut store, ())
58
.unwrap_err()
59
.downcast::<Trap>()?;
60
assert_eq!(trap, Trap::UnreachableCodeReached);
61
62
let trap = overflow
63
.call(&mut store, ())
64
.unwrap_err()
65
.downcast::<Trap>()?;
66
assert_eq!(trap, Trap::StackOverflow);
67
68
assert_host_signal_handlers_are_unset();
69
70
Ok(())
71
}
72
73
fn assert_host_signal_handlers_are_unset() {
74
#[cfg(unix)]
75
unsafe {
76
let mut prev = std::mem::zeroed::<libc::sigaction>();
77
let rc = libc::sigaction(libc::SIGILL, std::ptr::null(), &mut prev);
78
assert_eq!(rc, 0);
79
assert_eq!(
80
prev.sa_sigaction,
81
libc::SIG_DFL,
82
"fault handler was installed when it shouldn't have been"
83
);
84
}
85
#[cfg(windows)]
86
{
87
// Note that this can't be checked on Windows because vectored exception
88
// handlers work a bit differently and aren't as "global" as a signal
89
// handler. For now rely on the check above on unix to also guarantee
90
// that on Windows we don't register any vectored exception handlers.
91
}
92
}
93
94