fix(plugin_call): set rc to EXIT_SIGNALED_SIGABRT when wasmtime bails out on plugin call (#776)

Fixes #775

134/EXIT_SIGNALED_SIGABRT was chosen as the wasmtime CLI exits with it
executes `unreachable`.
This commit is contained in:
Gavin Hayes
2024-10-10 15:03:59 -04:00
committed by GitHub
parent 876a3be147
commit a91846a34b
3 changed files with 50 additions and 7 deletions

View File

@@ -867,19 +867,25 @@ impl Plugin {
let _ = self.timer_tx.send(TimerAction::Stop { id: self.id });
self.store_needs_reset = name == "_start";
let mut rc = 0;
let mut rc = -1;
if self.store.get_fuel().is_ok_and(|x| x == 0) {
res = Err(Error::msg("plugin ran out of fuel"));
rc = -1;
} else {
// Get extism error
self.get_output_after_call().map_err(|x| (x, -1))?;
if !results.is_empty() {
rc = results[0].i32().unwrap_or(-1);
debug!(plugin = self.id.to_string(), "got return code: {}", rc);
let output_res = self.get_output_after_call().map_err(|x| (x, -1));
// Get the return code
if output_res.is_ok() && res.is_ok() {
rc = 0;
if !results.is_empty() {
rc = results[0].i32().unwrap_or(-1);
debug!(plugin = self.id.to_string(), "got return code: {}", rc);
}
}
if self.output.error_offset != 0 && self.output.error_length != 0 {
// on extism error
if output_res.is_ok() && self.output.error_offset != 0 && self.output.error_length != 0
{
let handle = MemoryHandle {
offset: self.output.error_offset,
length: self.output.error_length,
@@ -904,6 +910,14 @@ impl Plugin {
)));
}
}
// on wasmtime error
} else if let Err(e) = &res {
if e.is::<wasmtime::Trap>() {
rc = 134; // EXIT_SIGNALED_SIGABRT
}
// if there was an error retrieving the output
} else {
output_res?;
}
}

View File

@@ -1,6 +1,7 @@
use crate::*;
const WASM_EMPTY: &[u8] = include_bytes!("../../../wasm/empty.wasm");
const WASM_UNREACHABLE: &[u8] = include_bytes!("../../../wasm/unreachable.wasm");
// https://github.com/extism/extism/issues/620
#[test]
@@ -26,3 +27,31 @@ host_fn!(
Ok(path.display().to_string())
}
);
// https://github.com/extism/extism/issues/775
#[test]
fn test_issue_775() {
// Load and build plugin
let url = Wasm::data(WASM_UNREACHABLE);
let manifest = Manifest::new([url]);
let mut plugin = PluginBuilder::new(manifest)
.with_wasi(true)
.build()
.unwrap();
// Call test method
let lock = plugin.instance.clone();
let mut lock = lock.lock().unwrap();
let res = plugin.raw_call(&mut lock, "do_unreachable", b"", None::<()>);
let p = match res {
Err(e) => {
if e.1 == 0 {
Err(e.1)
} else {
Ok(e.1)
}
}
Ok(code) => Err(code),
}
.unwrap();
println!("{}", p);
}

BIN
wasm/unreachable.wasm Executable file

Binary file not shown.