address more of zesterer's proposals and implement process exit removing the binary

This commit is contained in:
Christof Petig 2023-06-24 12:28:34 +02:00
parent 43f7bb7ddc
commit 65966294a0
5 changed files with 57 additions and 7 deletions

View File

@ -9,6 +9,7 @@ pub enum PluginError {
NoSuchModule,
Encoding(Box<ErrorKind>),
PluginModuleError(String, String, PluginModuleError),
ProcessExit,
}
#[derive(Debug)]

View File

@ -1,4 +1,4 @@
use crate::plugin::wasm_env::HostFunctionEnvironment;
use crate::plugin::wasm_env::{HostFunctionEnvironment, HostFunctionException};
use wasmer::{AsStoreMut, AsStoreRef, FunctionEnvMut, Memory32, Memory64, MemorySize, WasmPtr};
// there is no WASI defined for wasm64, yet, so always use 32bit pointers
type MemoryModel = wasmer::Memory32;
@ -105,6 +105,8 @@ pub(crate) fn wasi_env_get(
_environ: WasmPtr<WasmPtr<u8, MemoryModel>, MemoryModel>,
_environ_buf: WasmPtr<u8, MemoryModel>,
) -> i32 {
// as the environment is always empty (0 bytes, 0 entries) this function will
// just unconditionally return Success.
wasmer_wasix_types::wasi::Errno::Success as i32
}
@ -118,14 +120,18 @@ pub(crate) fn wasi_env_sizes_get(
let memory = env.data().memory().clone();
let store = env.as_store_mut();
let mem = memory.view(&store);
const NUMBER_OF_ENVIRONMENT_ENTRIES: u32 = 0;
const NUMBER_OF_ENVIRONMENT_BYTES: u32 = 0;
numptr
.write(&mem, 0)
.and_then(|()| bytesptr.write(&mem, 0))
.map(|()| Errno::Success)
.unwrap_or(Errno::Memviolation) as i32
.write(&mem, NUMBER_OF_ENVIRONMENT_ENTRIES)
.and_then(|()| bytesptr.write(&mem, NUMBER_OF_ENVIRONMENT_BYTES))
.map_or(Errno::Memviolation, |()| Errno::Success) as i32
}
// proc_exit(rval: exitcode)
pub(crate) fn wasi_proc_exit(env: FunctionEnvMut<HostFunctionEnvironment>, _exitcode: i32) {
tracing::warn!("Plugin {} called exit().", env.data().name)
pub(crate) fn wasi_proc_exit(
_env: FunctionEnvMut<HostFunctionEnvironment>,
exitcode: i32,
) -> Result<(), HostFunctionException> {
Err(HostFunctionException::ProcessExit(exitcode))
}

View File

@ -22,6 +22,7 @@ use self::{
errors::PluginError,
memory_manager::EcsWorld,
module::{PluginModule, PreparedEventQuery},
wasm_env::HostFunctionException,
};
use rayon::prelude::*;
@ -102,6 +103,24 @@ impl Plugin {
.flat_map(|module| {
module.try_execute(ecs, event).map(|x| {
x.map_err(|e| {
if let errors::PluginModuleError::RunFunction(runtime_err) = &e {
if let Some(host_except) =
runtime_err.downcast_ref::<HostFunctionException>()
{
match host_except {
HostFunctionException::ProcessExit(code) => {
module.exit_code = Some(*code);
tracing::warn!(
"Module {} binary {} exited with {}",
self.data.name,
module.name(),
*code
);
return PluginError::ProcessExit;
},
}
}
}
PluginError::PluginModuleError(
self.data.name.to_owned(),
event.get_function_name().to_owned(),
@ -111,6 +130,13 @@ impl Plugin {
})
})
.collect::<Result<Vec<_>, _>>()
.map_err(|e| {
if matches!(e, PluginError::ProcessExit) {
// remove the executable from the module which called process exit
self.modules.retain(|m| m.exit_code.is_none())
}
e
})
}
}

View File

@ -27,6 +27,7 @@ pub struct PluginModule {
store: Store,
#[allow(dead_code)]
name: String,
pub(crate) exit_code: Option<i32>,
}
impl PluginModule {
@ -125,6 +126,7 @@ impl PluginModule {
wasm_state: Arc::new(instance),
store,
name,
exit_code: None,
})
}
@ -151,6 +153,8 @@ impl PluginModule {
};
Some(bincode::deserialize(&bytes).map_err(PluginModuleError::Encoding))
}
pub fn name(&self) -> &str { &self.name }
}
/// This structure represent a Pre-encoded event object (Useful to avoid

View File

@ -26,6 +26,19 @@ pub struct HostFunctionEnvironmentInit {
memory: Memory,
}
#[derive(Debug, Clone, Copy)]
// Exception thrown from a native wasm callback
pub enum HostFunctionException {
ProcessExit(i32),
}
// needed for `std::error::Error`
impl core::fmt::Display for HostFunctionException {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{:?}", self) }
}
impl std::error::Error for HostFunctionException {}
impl HostFunctionEnvironment {
pub fn new(name: String, ecs: Arc<EcsAccessManager>) -> Self {
Self {