Expose TrapCode::Interrupt on epoch based interruption (#4105)

This commit is contained in:
Saúl Cabrera
2022-05-10 11:27:30 -04:00
committed by GitHub
parent 71fc16bbeb
commit 52524d258c
5 changed files with 16 additions and 20 deletions

View File

@@ -593,7 +593,7 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
// The reason is that one can construct a "zip-bomb-like" // The reason is that one can construct a "zip-bomb-like"
// program with exponential-in-program-size runtime, with no // program with exponential-in-program-size runtime, with no
// backedges (loops), by building a tree of function calls: f0 // backedges (loops), by building a tree of function calls: f0
// calls f1 ten tims, f1 calls f2 ten times, etc. E.g., nine // calls f1 ten times, f1 calls f2 ten times, etc. E.g., nine
// levels of this yields a billion function calls with no // levels of this yields a billion function calls with no
// backedges. So we can't do checks only at backedges. // backedges. So we can't do checks only at backedges.
// //

View File

@@ -1856,7 +1856,14 @@ unsafe impl<T> wasmtime_runtime::Store for StoreInner<T> {
fn new_epoch(&mut self) -> Result<u64, anyhow::Error> { fn new_epoch(&mut self) -> Result<u64, anyhow::Error> {
return match &self.epoch_deadline_behavior { return match &self.epoch_deadline_behavior {
&EpochDeadline::Trap => Err(anyhow::Error::new(EpochDeadlineError)), &EpochDeadline::Trap => {
let trap = Trap::new_wasm(
None,
wasmtime_environ::TrapCode::Interrupt,
wasmtime_runtime::Backtrace::new(),
);
Err(anyhow::Error::from(trap))
}
#[cfg(feature = "async")] #[cfg(feature = "async")]
&EpochDeadline::YieldAndExtendDeadline { delta } => { &EpochDeadline::YieldAndExtendDeadline { delta } => {
// Do the async yield. May return a trap if future was // Do the async yield. May return a trap if future was
@@ -1870,17 +1877,6 @@ unsafe impl<T> wasmtime_runtime::Store for StoreInner<T> {
Ok(self.get_epoch_deadline()) Ok(self.get_epoch_deadline())
} }
}; };
#[derive(Debug)]
struct EpochDeadlineError;
impl fmt::Display for EpochDeadlineError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("epoch deadline reached during execution")
}
}
impl std::error::Error for EpochDeadlineError {}
} }
} }

View File

@@ -29,7 +29,7 @@ fn main() -> Result<()> {
let trap = run.call(&mut store, ()).unwrap_err(); let trap = run.call(&mut store, ()).unwrap_err();
println!("trap received..."); println!("trap received...");
assert!(trap.to_string().contains("epoch deadline reached")); assert!(trap.trap_code().unwrap() == TrapCode::Interrupt);
Ok(()) Ok(())
} }

View File

@@ -175,7 +175,7 @@ fn timeout_in_start() -> Result<()> {
assert_eq!(output.stdout, b""); assert_eq!(output.stdout, b"");
let stderr = String::from_utf8_lossy(&output.stderr); let stderr = String::from_utf8_lossy(&output.stderr);
assert!( assert!(
stderr.contains("epoch deadline reached during execution"), stderr.contains("wasm trap: interrupt"),
"bad stderr: {}", "bad stderr: {}",
stderr stderr
); );
@@ -196,7 +196,7 @@ fn timeout_in_invoke() -> Result<()> {
assert_eq!(output.stdout, b""); assert_eq!(output.stdout, b"");
let stderr = String::from_utf8_lossy(&output.stderr); let stderr = String::from_utf8_lossy(&output.stderr);
assert!( assert!(
stderr.contains("epoch deadline reached during execution"), stderr.contains("wasm trap: interrupt"),
"bad stderr: {}", "bad stderr: {}",
stderr stderr
); );

View File

@@ -33,7 +33,7 @@ fn loops_interruptable() -> anyhow::Result<()> {
store.engine().increment_epoch(); store.engine().increment_epoch();
let trap = iloop.call(&mut store, ()).unwrap_err(); let trap = iloop.call(&mut store, ()).unwrap_err();
assert!( assert!(
trap.to_string().contains("epoch deadline reached"), trap.trap_code().unwrap() == TrapCode::Interrupt,
"bad message: {}", "bad message: {}",
trap trap
); );
@@ -50,7 +50,7 @@ fn functions_interruptable() -> anyhow::Result<()> {
store.engine().increment_epoch(); store.engine().increment_epoch();
let trap = iloop.call(&mut store, ()).unwrap_err(); let trap = iloop.call(&mut store, ()).unwrap_err();
assert!( assert!(
trap.to_string().contains("epoch deadline reached"), trap.trap_code().unwrap() == TrapCode::Interrupt,
"{}", "{}",
trap.to_string() trap.to_string()
); );
@@ -103,7 +103,7 @@ fn loop_interrupt_from_afar() -> anyhow::Result<()> {
thread.join().unwrap(); thread.join().unwrap();
assert!(HITS.load(SeqCst) > NUM_HITS); assert!(HITS.load(SeqCst) > NUM_HITS);
assert!( assert!(
trap.to_string().contains("epoch deadline reached"), trap.trap_code().unwrap() == TrapCode::Interrupt,
"bad message: {}", "bad message: {}",
trap.to_string() trap.to_string()
); );
@@ -143,7 +143,7 @@ fn function_interrupt_from_afar() -> anyhow::Result<()> {
thread.join().unwrap(); thread.join().unwrap();
assert!(HITS.load(SeqCst) > NUM_HITS); assert!(HITS.load(SeqCst) > NUM_HITS);
assert!( assert!(
trap.to_string().contains("epoch deadline reached"), trap.trap_code().unwrap() == TrapCode::Interrupt,
"bad message: {}", "bad message: {}",
trap.to_string() trap.to_string()
); );