fix: stacks at top of user VA in own 1 MiB band (guard, heap kept below), 8/16 pages default; kernel fault msg names pid, kind, flags stack overflow; flaky OVERFLOW + spawntest/test-qemu check it
This commit is contained in:
@@ -16,6 +16,16 @@ pub mod op {
|
||||
pub const CRASH: usize = 2;
|
||||
/// Blocks for good inside the handler.
|
||||
pub const HANG: usize = 3;
|
||||
/// Recurses until its stack runs out: the kernel says it overflowed.
|
||||
pub const OVERFLOW: usize = 4;
|
||||
}
|
||||
|
||||
/// Ever deeper, a KiB of stack a call, until there is none.
|
||||
#[allow(unconditional_recursion, reason = "running off the stack is what it is for")]
|
||||
fn deeper(n: usize) -> usize {
|
||||
let frame = core::hint::black_box([n as u8; 1024]);
|
||||
// Used after the call, so the call is not a jump.
|
||||
deeper(n + 1) + frame[n % 1024] as usize
|
||||
}
|
||||
|
||||
/// Everything goes through `handle_call`.
|
||||
@@ -49,6 +59,9 @@ impl Server for Flaky {
|
||||
match words[0] {
|
||||
op::WHO => {}
|
||||
op::CRASH => panic!("asked to crash"),
|
||||
op::OVERFLOW => {
|
||||
core::hint::black_box(deeper(0));
|
||||
}
|
||||
op::HANG => {
|
||||
// A notification nobody signals.
|
||||
if let Ok(never) = syscall::create_notification() {
|
||||
|
||||
@@ -267,6 +267,16 @@ fn restarted_after_hanging() -> Result<(), &'static str> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A server that runs off its stack faults on the guard below it, and is
|
||||
/// restarted like any other that died.
|
||||
fn restarted_after_overflowing() -> Result<(), &'static str> {
|
||||
let _ = syscall::request(FLAKY, [flaky::op::OVERFLOW, 0, 0, 0]);
|
||||
if flaky()? != 1 {
|
||||
return Err("the overflowed server was not restarted");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check() -> Result<(), &'static str> {
|
||||
let mut fs = Storage::attach(STORAGE, STORAGE_BUF_VA).map_err(|_| "cannot attach to storage")?;
|
||||
write_a_file(&mut fs)?;
|
||||
@@ -305,6 +315,9 @@ fn check() -> Result<(), &'static str> {
|
||||
|
||||
restarted_after_hanging()?;
|
||||
libkos::println!("spawntest: a hung server is noticed, stopped and restarted: ok");
|
||||
|
||||
restarted_after_overflowing()?;
|
||||
libkos::println!("spawntest: a server that overflows its stack is caught and restarted: ok");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user