diff --git a/selene-core/rust/error_model/helper.rs b/selene-core/rust/error_model/helper.rs index 5a71c454..c3936b1d 100644 --- a/selene-core/rust/error_model/helper.rs +++ b/selene-core/rust/error_model/helper.rs @@ -2,6 +2,15 @@ //! error model plugins as rust crates. //! //! See `selene-ideal-error-model-plugin` for a fully worked example. +use anyhow::{Result, anyhow}; +use std::{ + ffi, mem, + panic::{self, UnwindSafe}, + sync::Arc, +}; + +use crate::utils::{convert_cargs_to_strings, result_of_errno_to_errno, result_to_errno}; + use super::{ ErrorModelInterface, interface::ErrorModelInterfaceFactory, @@ -12,8 +21,6 @@ use super::{ use crate::runtime::plugin::{ BatchBuilder, RuntimeExtractOperationInstance, RuntimeExtractOperationInterface, }; -use crate::utils::{convert_cargs_to_strings, result_of_errno_to_errno, result_to_errno}; -use std::{ffi, mem, sync::Arc}; #[derive(Default)] /// A helper struct used by [crate::export_error_model_plugin!] to implement the error model @@ -31,14 +38,18 @@ impl Helper { unsafe { Box::from_raw(instance as *mut F::Interface) } } - fn with_error_model_instance( + fn with_error_model_instance( instance: ErrorModelInstance, - mut go: impl FnMut(&mut F::Interface) -> T, - ) -> T { - let mut e = unsafe { Self::from_error_model_instance(instance) }; - let t = go(&mut e); - mem::forget(e); - t + mut go: impl FnMut(&mut F::Interface) -> Result + UnwindSafe, + ) -> Result { + panic::catch_unwind(move || { + assert!(!instance.is_null()); + let mut e = unsafe { Self::from_error_model_instance(instance) }; + let t = go(&mut e); + mem::forget(e); + t + }) + .map_err(|_| anyhow!("error model plugin panicked"))? } fn factory(&self) -> Arc { diff --git a/selene-core/rust/runtime/helper.rs b/selene-core/rust/runtime/helper.rs index 42cb6005..84228a93 100644 --- a/selene-core/rust/runtime/helper.rs +++ b/selene-core/rust/runtime/helper.rs @@ -43,7 +43,7 @@ impl Helper { mem::forget(r); t }) - .map_err(|_| anyhow!("runtime panicked"))? + .map_err(|_| anyhow!("runtime plugin panicked"))? } fn factory(&self) -> Arc { diff --git a/selene-core/rust/simulator/helper.rs b/selene-core/rust/simulator/helper.rs index aa9d0e73..f552600a 100644 --- a/selene-core/rust/simulator/helper.rs +++ b/selene-core/rust/simulator/helper.rs @@ -2,14 +2,18 @@ //! error model plugins as rust crates. //! //! See `selene-coinflip-plugin` for an example of how to implement a plugin. -use std::{ffi, mem, sync::Arc}; - use super::{ SimulatorInterface, interface::SimulatorInterfaceFactory, plugin::{Errno, SimulatorInstance}, }; use crate::utils::{convert_cargs_to_strings, result_of_errno_to_errno, result_to_errno}; +use anyhow::{Result, anyhow}; +use std::{ + ffi, mem, + panic::{self, UnwindSafe}, + sync::Arc, +}; #[derive(Default)] /// A helper struct used by [crate::export_simulator_plugin] to implement the simulator @@ -27,14 +31,17 @@ impl Helper { unsafe { Box::from_raw(instance as *mut F::Interface) } } - fn with_simulator_instance( + fn with_simulator_instance( instance: SimulatorInstance, - mut go: impl FnMut(&mut F::Interface) -> T, - ) -> T { - let mut s = unsafe { Self::from_simulator_instance(instance) }; - let t = go(&mut s); - mem::forget(s); - t + mut go: impl FnMut(&mut F::Interface) -> Result + UnwindSafe, + ) -> Result { + panic::catch_unwind(move || { + let mut s = unsafe { Self::from_simulator_instance(instance) }; + let t = go(&mut s); + mem::forget(s); + t + }) + .map_err(|_| anyhow!("simulator plugin panicked"))? } fn factory(&self) -> Arc {