wasmtime/runtime/vm/traphandlers/signals.rs
1//! Trap handling support when `has_native_signals` is enabled.
2//!
3//! This module is conditionally included in the above `traphandlers` module and
4//! contains support and shared routines for working with signals-based traps.
5//! Each platform will have its own `signals-based-traps` configuration and
6//! thise module serves as a shared entrypoint for initialization entrypoints
7//! (`init_traps`) and testing if a trapping opcode is wasm (`test_if_trap`).
8
9use crate::sync::RwLock;
10use crate::vm::sys::traphandlers::TrapHandler;
11
12/// Platform-specific trap-handler state.
13///
14/// This state is protected by a lock to synchronize access to it. Right now
15/// it's a `RwLock` but it could be a `Mutex`, and `RwLock` is just chosen for
16/// convenience as it's what's implemented in no_std. The performance here
17/// should not be of consequence.
18///
19/// This is initialized to `None` and then set as part of `init_traps`.
20static TRAP_HANDLER: RwLock<Option<TrapHandler>> = RwLock::new(None);
21
22/// This function is required to be called before any WebAssembly is entered.
23/// This will configure global state such as signal handlers to prepare the
24/// process to receive wasm traps.
25///
26/// # Panics
27///
28/// This function will panic on macOS if it is called twice or more times with
29/// different values of `macos_use_mach_ports`.
30///
31/// This function will also panic if the `std` feature is disabled and it's
32/// called concurrently.
33pub fn init_traps(macos_use_mach_ports: bool) {
34 let mut lock = TRAP_HANDLER.write();
35 match lock.as_mut() {
36 Some(state) => state.validate_config(macos_use_mach_ports),
37 None => *lock = Some(unsafe { TrapHandler::new(macos_use_mach_ports) }),
38 }
39}
40
41/// De-initializes platform-specific state for trap handling.
42///
43/// # Panics
44///
45/// This function will also panic if the `std` feature is disabled and it's
46/// called concurrently.
47///
48/// # Aborts
49///
50/// This may abort the process on some platforms where trap handling state
51/// cannot be unloaded.
52///
53/// # Unsafety
54///
55/// This is not safe to be called unless all wasm code is unloaded. This is not
56/// safe to be called on some platforms, like Unix, when other libraries
57/// installed their own signal handlers after `init_traps` was called.
58///
59/// There's more reasons for unsafety here than those articulated above,
60/// generally this can only be called "if you know what you're doing".
61pub unsafe fn deinit_traps() {
62 let mut lock = TRAP_HANDLER.write();
63 let _ = lock.take();
64}