This repository was archived by the owner on Mar 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 167
This repository was archived by the owner on Mar 24, 2022. It is now read-only.
Instance::run panics if another instance trapped in the same thread #323
Copy link
Copy link
Open
Description
It looks like thread-local state becomes infected once an instance traps (e.g. by executing unreachable), and when the next instance is created in the same thread, it panics with the following backtrace:
thread '<unnamed>' panicked at 'enabling or changing the signal stack succeeds: Sys(EPERM)', src/libcore/result.rs:1084:5
stack backtrace:
0: std::sys_common::backtrace::print
1: std::panicking::default_hook::{{closure}}
2: std::panicking::default_hook
3: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
4: std::panicking::continue_panic_fmt
5: std::panicking::try::do_call
6: <T as core::any::Any>::type_id
7: core::ptr::real_drop_in_place
8: core::result::Result<T,E>::expect
at /private/tmp/nix-build-rustc-1.38.0.drv-0/rustc-1.38.0-src/src/libcore/result.rs:879
9: lucet_runtime_internals::instance::signals::<impl lucet_runtime_internals::instance::Instance>::with_signals_on
at /Users/lifted/Projects/dfinity/rs/.cargo-home/registry/src/github.com-1ecc6299db9ec823/lucet-runtime-internals-0.1.1/src/instance/signals.rs:65
10: lucet_runtime_internals::instance::Instance::run_func
at /Users/lifted/Projects/dfinity/rs/.cargo-home/registry/src/github.com-1ecc6299db9ec823/lucet-runtime-internals-0.1.1/src/instance.rs:612
11: lucet_runtime_internals::instance::Instance::run
The panic comes from this place:
impl Instance {
pub(crate) fn with_signals_on<F, R>(&mut self, f: F) -> Result<R, Error>
where
F: FnOnce(&mut Instance) -> Result<R, Error>,
{
// Set up the signal stack for this thread. Note that because signal stacks are per-thread,
// rather than per-process, we do this for every run, while the signal handler is installed
// only once per process.
let guest_sigstack = SigStack::new(
self.alloc.slot().sigstack,
SigStackFlags::empty(),
libc::SIGSTKSZ,
);
let previous_sigstack = unsafe { sigaltstack(Some(guest_sigstack)) } // <-- PANICS
.expect("enabling or changing the signal stack succeeds");You can reproduce the issue using the following small crate:
src/main.rs
use lucet_runtime::{DlModule, MmapRegion, Region};
use lucet_runtime_internals::alloc::Limits;
use lucetc::Lucetc;
fn main() {
let wasm = wabt::wat2wasm(
r#"
(module
(func (export "trap") unreachable)
(func (export "test")))
"#,
)
.unwrap();
let lucetc = Lucetc::try_from_bytes(wasm.as_slice()).unwrap();
lucetc.shared_object_file("mod.so").unwrap();
let module = DlModule::load("mod.so").unwrap();
let memory: std::sync::Arc<MmapRegion> = MmapRegion::create(1, &Limits::default()).unwrap();
for func_name in &["trap", "test"] {
let mut instance_handle = memory.new_instance_builder(module.clone()).build().unwrap();
println!("{:?}", instance_handle.run(func_name, &[]));
}
}Cargo.toml
[package]
name = "min-example"
version = "0.1.0"
edition = "2018"
[dependencies]
lucet-runtime = "0.1.1"
lucetc = "0.1.1"
lucet-runtime-internals = "0.1.1"
wabt = "0.7.4"Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels