diff --git a/crates/fiber/src/windows.rs b/crates/fiber/src/windows.rs index e61f11d8d3..be35ae4e15 100644 --- a/crates/fiber/src/windows.rs +++ b/crates/fiber/src/windows.rs @@ -5,6 +5,7 @@ use std::ptr; use winapi::shared::minwindef::*; use winapi::shared::winerror::ERROR_NOT_SUPPORTED; use winapi::um::fibersapi::*; +use winapi::um::processthreadsapi::SetThreadStackGuarantee; use winapi::um::winbase::*; #[derive(Debug)] @@ -49,6 +50,13 @@ unsafe extern "system" fn fiber_start(data: LPVOID) where F: FnOnce(A, &super::Suspend) -> C, { + // Set the stack guarantee to be consistent with what Rust expects for threads + // This value is taken from: + // https://github.com/rust-lang/rust/blob/0d97f7a96877a96015d70ece41ad08bb7af12377/library/std/src/sys/windows/stack_overflow.rs + if SetThreadStackGuarantee(&mut 0x5000) == 0 { + panic!("failed to set fiber stack guarantee"); + } + let state = data.cast::(); let func = Box::from_raw((*state).initial_closure.get().cast::()); (*state).initial_closure.set(ptr::null_mut()); diff --git a/tests/host_segfault.rs b/tests/host_segfault.rs index 5efa1d6f83..e725ff4303 100644 --- a/tests/host_segfault.rs +++ b/tests/host_segfault.rs @@ -29,13 +29,20 @@ fn segfault() -> ! { } } -fn overrun_the_stack() -> usize { - let mut a = [0u8; 1024]; - if a.as_mut_ptr() as usize == 1 { - return 1; - } else { - return a.as_mut_ptr() as usize + overrun_the_stack(); +fn allocate_stack_space() -> ! { + let _a = [0u8; 1024]; + + for _ in 0..100000 { + allocate_stack_space(); } + + unreachable!() +} + +fn overrun_the_stack() -> ! { + println!("{}", CONFIRM); + io::stdout().flush().unwrap(); + allocate_stack_space(); } fn run_future(future: F) -> F::Output { @@ -104,8 +111,6 @@ fn main() { let store = Store::new(&engine); let module = Module::new(&engine, "(module)").unwrap(); let _instance = Instance::new(&store, &module, &[]).unwrap(); - println!("{}", CONFIRM); - io::stdout().flush().unwrap(); overrun_the_stack(); }, true, @@ -118,6 +123,7 @@ fn main() { let module = Module::new(&engine, r#"(import "" "" (func)) (start 0)"#).unwrap(); let segfault = Func::wrap(&store, || segfault()); Instance::new(&store, &module, &[segfault.into()]).unwrap(); + unreachable!(); }, false, ), @@ -130,8 +136,6 @@ fn main() { let store = Store::new(&engine); let f = Func::wrap0_async(&store, (), |_, _| { Box::new(async { - print!("{}", CONFIRM); - io::stdout().flush().unwrap(); overrun_the_stack(); }) }); @@ -150,8 +154,6 @@ fn main() { let store = Store::new(&engine); let f = Func::wrap0_async(&store, (), |_, _| { Box::new(async { - println!("{}", CONFIRM); - io::stdout().flush().unwrap(); overrun_the_stack(); }) });