Use the psm crate to figure out the current stack pointer (#2358)
Currently the runtime needs to acquire the current stack pointer so it can set a limit for where if the wasm stack goes below that point it will abort the wasm code. Acquiring the stack pointer is done in a brittle way right now which involves looking at the address of what we hope is an on-stack structure. This turns out to not work at all with ASan as well. Instead this commit switches to the `psm` crate which is used by the Rust compiler team for stack manipulation, namely a coarse version of segmented stacks to avoid stack overflow in the compiler. We don't need most of the implementation of `psm`, just the `stack_pointer` function, but it shouldn't be a burden to bring in! Closes #2344
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -1397,6 +1397,15 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psm"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96e0536f6528466dbbbbe6b986c34175a8d0ff25b794c4bacda22e068cd2f2c5"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-error"
|
name = "quick-error"
|
||||||
version = "1.2.3"
|
version = "1.2.3"
|
||||||
@@ -2572,6 +2581,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"more-asserts",
|
"more-asserts",
|
||||||
|
"psm",
|
||||||
"region",
|
"region",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasmtime-environ",
|
"wasmtime-environ",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ more-asserts = "0.2.1"
|
|||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
backtrace = "0.3.49"
|
backtrace = "0.3.49"
|
||||||
lazy_static = "1.3.0"
|
lazy_static = "1.3.0"
|
||||||
|
psm = "0.1.11"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi"] }
|
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi"] }
|
||||||
|
|||||||
@@ -499,9 +499,18 @@ impl<'a> CallThreadState<'a> {
|
|||||||
/// Note that this function must be called with `self` on the stack, not the
|
/// Note that this function must be called with `self` on the stack, not the
|
||||||
/// heap/etc.
|
/// heap/etc.
|
||||||
fn update_stack_limit(&self, max_wasm_stack: usize) -> Result<impl Drop + '_, Trap> {
|
fn update_stack_limit(&self, max_wasm_stack: usize) -> Result<impl Drop + '_, Trap> {
|
||||||
// Make an "educated guess" to figure out where the wasm sp value should
|
// Determine the stack pointer where, after which, any wasm code will
|
||||||
// start trapping if it drops below.
|
// immediately trap. This is checked on the entry to all wasm functions.
|
||||||
let wasm_stack_limit = self as *const _ as usize - max_wasm_stack;
|
//
|
||||||
|
// Note that this isn't 100% precise. We are requested to give wasm
|
||||||
|
// `max_wasm_stack` bytes, but what we're actually doing is giving wasm
|
||||||
|
// probably a little less than `max_wasm_stack` because we're
|
||||||
|
// calculating the limit relative to this function's approximate stack
|
||||||
|
// pointer. Wasm will be executed on a frame beneath this one (or next
|
||||||
|
// to it). In any case it's expected to be at most a few hundred bytes
|
||||||
|
// of slop one way or another. When wasm is typically given a MB or so
|
||||||
|
// (a million bytes) the slop shouldn't matter too much.
|
||||||
|
let wasm_stack_limit = psm::stack_pointer() as usize - max_wasm_stack;
|
||||||
|
|
||||||
let interrupts = unsafe { &**(&*self.vmctx).instance().interrupts() };
|
let interrupts = unsafe { &**(&*self.vmctx).instance().interrupts() };
|
||||||
let reset_stack_limit = match interrupts.stack_limit.compare_exchange(
|
let reset_stack_limit = match interrupts.stack_limit.compare_exchange(
|
||||||
|
|||||||
Reference in New Issue
Block a user