Created
October 22, 2025 15:21
-
-
Save alexcrichton/0e87ad78de92f7ada9112d34e1012f8e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/crates/wasmtime/src/runtime/debug.rs b/crates/wasmtime/src/runtime/debug.rs | |
| index 0977bf8bc8..374e3d11c5 100644 | |
| --- a/crates/wasmtime/src/runtime/debug.rs | |
| +++ b/crates/wasmtime/src/runtime/debug.rs | |
| @@ -3,11 +3,9 @@ | |
| use crate::{ | |
| AnyRef, AsContext, AsContextMut, ExnRef, ExternRef, Func, Instance, Module, OwnedRooted, | |
| StoreContext, StoreContextMut, Val, | |
| - prelude::Box, | |
| store::{AutoAssertNoGc, StoreOpaque}, | |
| vm::{CurrentActivationBacktrace, VMContext}, | |
| }; | |
| -use alloc::sync::Arc; | |
| use alloc::vec; | |
| use alloc::vec::Vec; | |
| use core::{ffi::c_void, ptr::NonNull}; | |
| @@ -451,9 +449,9 @@ impl<'a, T: 'static> AsContextMut for DebugFrameCursor<'a, T> { | |
| /// One debug event that occurs when running Wasm code on a store with | |
| /// a debug handler attached. | |
| #[derive(Debug)] | |
| -pub enum DebugEvent { | |
| +pub enum DebugEvent<'a> { | |
| /// An `anyhow::Error` was raised by a hostcall. | |
| - HostcallError, | |
| + HostcallError(&'a anyhow::Error), | |
| /// An exception is thrown and caught by Wasm. The current state | |
| /// is at the throw-point. | |
| CaughtExceptionThrown(OwnedRooted<ExnRef>), | |
| @@ -499,15 +497,15 @@ pub enum DebugEvent { | |
| /// another async stack, and the stack that polls the future | |
| /// running a particular Wasm invocation could change after each | |
| /// suspend point in the handler. | |
| -pub trait DebugHandler: Send + Sync + 'static { | |
| +pub trait DebugHandler: Clone + Send + Sync + 'static { | |
| /// The data expected on the store that this handler is attached | |
| /// to. | |
| type Data; | |
| /// Handle a debug event. | |
| - fn handle<'a>( | |
| - self: Arc<Self>, | |
| - store: StoreContextMut<'a, Self::Data>, | |
| - event: DebugEvent, | |
| - ) -> Box<dyn Future<Output = ()> + Send + 'a>; | |
| + fn handle( | |
| + &self, | |
| + store: StoreContextMut<'_, Self::Data>, | |
| + event: DebugEvent<'_>, | |
| + ) -> impl Future<Output = ()> + Send; | |
| } | |
| diff --git a/crates/wasmtime/src/runtime/store.rs b/crates/wasmtime/src/runtime/store.rs | |
| index e44eccd0bc..894f1ec5a4 100644 | |
| --- a/crates/wasmtime/src/runtime/store.rs | |
| +++ b/crates/wasmtime/src/runtime/store.rs | |
| @@ -272,7 +272,34 @@ pub struct StoreInner<T: 'static> { | |
| /// `StoreContextMut`); so we need to hold a separate reference to | |
| /// it while invoking it. | |
| #[cfg(feature = "debug")] | |
| - pub(crate) debug_handler: Option<Arc<dyn DebugHandler<Data = T>>>, | |
| + debug_handler: Option<Box<dyn StoreDebugHandler<T>>>, | |
| +} | |
| + | |
| +// Internal adapter from `DebugHandler` to something object-safe. | |
| +#[cfg(feature = "debug")] | |
| +trait StoreDebugHandler<T: 'static>: Send + Sync { | |
| + fn handle<'a>( | |
| + self: Box<Self>, | |
| + store: StoreContextMut<'a, T>, | |
| + event: crate::DebugEvent<'a>, | |
| + ) -> Box<dyn Future<Output = ()> + Send + 'a>; | |
| +} | |
| + | |
| +#[cfg(feature = "debug")] | |
| +impl<D> StoreDebugHandler<D::Data> for D | |
| +where | |
| + D: DebugHandler, | |
| + D::Data: Send, | |
| +{ | |
| + fn handle<'a>( | |
| + self: Box<Self>, | |
| + store: StoreContextMut<'a, D::Data>, | |
| + event: crate::DebugEvent<'a>, | |
| + ) -> Box<dyn Future<Output = ()> + Send + 'a> { | |
| + let handler: D = (*self).clone(); | |
| + store.0.debug_handler = Some(self); | |
| + Box::new(async move { handler.handle(store, event).await }) | |
| + } | |
| } | |
| enum ResourceLimiterInner<T> { | |
| @@ -1250,7 +1277,7 @@ impl<T> Store<T> { | |
| self.engine().tunables().debug_guest, | |
| "debug hooks require guest debugging to be enabled" | |
| ); | |
| - self.inner.debug_handler = Some(Arc::new(handler)); | |
| + self.inner.debug_handler = Some(Box::new(handler)); | |
| } | |
| /// Clear the debug handler on this store. If any existed, it will | |
| @@ -2720,10 +2747,12 @@ unsafe impl<T> VMStore for StoreInner<T> { | |
| } | |
| #[cfg(feature = "debug")] | |
| - fn block_on_debug_handler(&mut self, event: crate::DebugEvent) -> anyhow::Result<()> { | |
| - if let Some(handler) = self.debug_handler.as_ref().cloned() { | |
| + fn block_on_debug_handler(&mut self, event: crate::DebugEvent<'_>) -> anyhow::Result<()> { | |
| + if let Some(handler) = self.debug_handler.take() { | |
| log::trace!("about to raise debug event {event:?}"); | |
| - StoreContextMut(self).block_on(|store| Pin::from(handler.handle(store, event))) | |
| + StoreContextMut(self).with_blocking(|store, cx| { | |
| + cx.block_on(Pin::from(handler.handle(store, event)).as_mut()) | |
| + }) | |
| } else { | |
| Ok(()) | |
| } | |
| diff --git a/crates/wasmtime/src/runtime/vm/traphandlers.rs b/crates/wasmtime/src/runtime/vm/traphandlers.rs | |
| index c4733efbcf..353f8e6083 100644 | |
| --- a/crates/wasmtime/src/runtime/vm/traphandlers.rs | |
| +++ b/crates/wasmtime/src/runtime/vm/traphandlers.rs | |
| @@ -857,9 +857,9 @@ impl CallThreadState { | |
| .. | |
| } => store.block_on_debug_handler(crate::DebugEvent::Trap(*trap)), | |
| UnwindState::UnwindToHost { | |
| - reason: UnwindReason::Trap(TrapReason::User(_)), | |
| + reason: UnwindReason::Trap(TrapReason::User(err)), | |
| .. | |
| - } => store.block_on_debug_handler(crate::DebugEvent::HostcallError), | |
| + } => store.block_on_debug_handler(crate::DebugEvent::HostcallError(err)), | |
| UnwindState::UnwindToHost { | |
| reason: UnwindReason::Trap(TrapReason::Jit { .. }), |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment