Keep frame info registered until internal instance is gone (#1514)

This commit fixes an issue where the global registration of frame data
goes away once the `wasmtime::Module` has been dropped. Even after this
has been dropped, though, there may still be `wasmtime::Func` instances
which reference the original module, so it's only once the underlying
`wasmtime_runtime::Instance` has gone away that we can drop everything.

Closes #1479
This commit is contained in:
Alex Crichton
2020-04-16 14:00:49 -05:00
committed by GitHub
parent 7da6101732
commit 99adc1d218
5 changed files with 38 additions and 34 deletions

View File

@@ -3,6 +3,7 @@ use crate::module::Module;
use crate::runtime::{Config, Store};
use crate::trap::Trap;
use anyhow::{bail, Error, Result};
use std::any::Any;
use wasmtime_jit::{CompiledModule, Resolver};
use wasmtime_runtime::{Export, InstanceHandle, InstantiationError, SignatureRegistry};
@@ -23,6 +24,7 @@ fn instantiate(
compiled_module: &CompiledModule,
imports: &[Extern],
sig_registry: &SignatureRegistry,
host: Box<dyn Any>,
) -> Result<InstanceHandle, Error> {
let mut resolver = SimpleResolver { imports };
unsafe {
@@ -32,6 +34,7 @@ fn instantiate(
&mut resolver,
sig_registry,
config.memory_creator.as_ref().map(|a| a as _),
host,
)
.map_err(|e| -> Error {
match e {
@@ -132,13 +135,14 @@ impl Instance {
);
}
module.register_frame_info();
let info = module.register_frame_info();
let config = store.engine().config();
let instance_handle = instantiate(
config,
module.compiled_module(),
imports,
store.compiler().signatures(),
Box::new(info),
)?;
let mut exports = Vec::with_capacity(module.exports().len());

View File

@@ -137,7 +137,7 @@ struct ModuleInner {
imports: Box<[ImportType]>,
exports: Box<[ExportType]>,
compiled: CompiledModule,
frame_info_registration: Mutex<Option<Option<GlobalFrameInfoRegistration>>>,
frame_info_registration: Mutex<Option<Option<Arc<GlobalFrameInfoRegistration>>>>,
}
impl Module {
@@ -665,11 +665,13 @@ and for re-adding support for interface types you can see this issue:
/// Register this module's stack frame information into the global scope.
///
/// This is required to ensure that any traps can be properly symbolicated.
pub(crate) fn register_frame_info(&self) {
pub(crate) fn register_frame_info(&self) -> Option<Arc<GlobalFrameInfoRegistration>> {
let mut info = self.inner.frame_info_registration.lock().unwrap();
if info.is_some() {
return;
if let Some(info) = &*info {
return info.clone();
}
*info = Some(super::frame_info::register(&self.inner.compiled));
let ret = super::frame_info::register(&self.inner.compiled).map(Arc::new);
*info = Some(ret.clone());
return ret;
}
}