Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 1ed8892

Browse files
committed
fix memory leak when panicking with detached ComponentInstance
In `ComponentInstance::from_vmctx` and `StoreContextMut::with_detached_instance[_async]` we were leaking memory due to having taken `InstanceData` out of the `Store` and making it unreachable except via a raw pointer, meaning there was nothing responsible for dropping it on panic. This commit adds an RAII wrapper to take care of that. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
1 parent 90e7e16 commit 1ed8892

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

crates/wasmtime/src/runtime/component/concurrent.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,14 @@ impl fmt::Debug for WorkItem {
685685
}
686686
}
687687

688+
struct DataDropper<'a>(&'a mut ComponentInstance);
689+
690+
impl Drop for DataDropper<'_> {
691+
fn drop(&mut self) {
692+
drop(self.0.data.take());
693+
}
694+
}
695+
688696
impl<T> StoreContextMut<'_, T> {
689697
/// Temporarily split the specified store and instance into a "detached"
690698
/// state (i.e. clearing the pointers they have to each other) so that they
@@ -721,11 +729,12 @@ impl<T> StoreContextMut<'_, T> {
721729
// it and can take an exclusive reference to it.
722730
let instance = unsafe { &mut *data.instance_ptr() };
723731
assert!(instance.data.is_none());
724-
instance.data = Some(data);
725-
instance.set_store(None);
726-
let result = fun(self.as_context_mut(), instance);
727-
instance.set_store(Some(VMStoreRawPtr(self.traitobj())));
728-
(result, instance.data.take())
732+
let instance = DataDropper(instance);
733+
instance.0.data = Some(data);
734+
instance.0.set_store(None);
735+
let result = fun(self.as_context_mut(), instance.0);
736+
instance.0.set_store(Some(VMStoreRawPtr(self.traitobj())));
737+
(result, instance.0.data.take())
729738
};
730739
if self.0[instance.0].is_none() {
731740
self.0[instance.0] = data;
@@ -753,10 +762,11 @@ impl<T> StoreContextMut<'_, T> {
753762
let instance = unsafe { &mut *data.instance_ptr() };
754763
assert!(instance.data.is_none());
755764
instance.data = Some(data);
756-
instance.set_store(None);
757-
let result = fun(self.as_context_mut(), instance).await;
758-
instance.set_store(Some(VMStoreRawPtr(self.traitobj())));
759-
(result, instance.data.take())
765+
let instance = DataDropper(instance);
766+
instance.0.set_store(None);
767+
let result = fun(self.as_context_mut(), instance.0).await;
768+
instance.0.set_store(Some(VMStoreRawPtr(self.traitobj())));
769+
(result, instance.0.data.take())
760770
};
761771
if self.0[instance.0].is_none() {
762772
self.0[instance.0] = data;

0 commit comments

Comments
 (0)