From 3152df96400a6dec0624609a7b0f78e0f44b537e Mon Sep 17 00:00:00 2001 From: "zed-zippy[bot]" <234243425+zed-zippy[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 08:45:44 +0100 Subject: [PATCH] extension_host: Fix `IS_WASM_THREAD` being set for wrong threads (#43005) (cherry-pick to stable) (#43016) Cherry-pick of #43005 to stable ---- https://github.com/zed-industries/zed/pull/40883 implemented this incorrectly. It was marking a random background thread as a wasm thread (whatever thread picked up the wasm epoch timer background task), instead of marking the threads that actually run the wasm extension. This has two implications: 1. it didn't prevent extension panics from tearing down as planned 2. Worse, it actually made us hide legit panics in sentry for one of our background workers. Now 2 still technically applies for all tokio threads after this, but we basically only use these for wasm extensions in the main zed binary. Release Notes: - Fixed extension panics crashing Zed on Linux --------- Co-authored-by: Lukas Wirth --- crates/crashes/src/crashes.rs | 1 + crates/extension_host/src/wasm_host.rs | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/crashes/src/crashes.rs b/crates/crashes/src/crashes.rs index 560ca5a009d5ddf8f3866591ebd9e6247bc98942..97064b96d19b69e31c5f112e65682da0684fd5b9 100644 --- a/crates/crashes/src/crashes.rs +++ b/crates/crashes/src/crashes.rs @@ -289,6 +289,7 @@ impl minidumper::ServerHandler for CrashServer { pub fn panic_hook(info: &PanicHookInfo) { // Don't handle a panic on threads that are not relevant to the main execution. if extension_host::wasm_host::IS_WASM_THREAD.with(|v| v.load(Ordering::Acquire)) { + log::error!("wasm thread panicked!"); return; } diff --git a/crates/extension_host/src/wasm_host.rs b/crates/extension_host/src/wasm_host.rs index 1e4bed7a50b44c710384f19c901e4e74854df0e2..1fe8d0117f36b25a5a83fe574006adeb7f7ef035 100644 --- a/crates/extension_host/src/wasm_host.rs +++ b/crates/extension_host/src/wasm_host.rs @@ -537,7 +537,6 @@ fn wasm_engine(executor: &BackgroundExecutor) -> wasmtime::Engine { let engine_ref = engine.weak(); executor .spawn(async move { - IS_WASM_THREAD.with(|v| v.store(true, Ordering::Release)); // Somewhat arbitrary interval, as it isn't a guaranteed interval. // But this is a rough upper bound for how long the extension execution can block on // `Future::poll`. @@ -643,6 +642,12 @@ impl WasmHost { let (tx, mut rx) = mpsc::unbounded::(); let extension_task = async move { + // note: Setting the thread local here will slowly "poison" all tokio threads + // causing us to not record their panics any longer. + // + // This is fine though, the main zed binary only uses tokio for livekit and wasm extensions. + // Livekit seldom (if ever) panics 🤞 so the likelihood of us missing a panic in sentry is very low. + IS_WASM_THREAD.with(|v| v.store(true, Ordering::Release)); while let Some(call) = rx.next().await { (call)(&mut extension, &mut store).await; } @@ -659,8 +664,8 @@ impl WasmHost { cx.spawn(async move |cx| { let (extension_task, manifest, work_dir, tx, zed_api_version) = cx.background_executor().spawn(load_extension_task).await?; - // we need to run run the task in an extension context as wasmtime_wasi may - // call into tokio, accessing its runtime handle + // we need to run run the task in a tokio context as wasmtime_wasi may + // call into tokio, accessing its runtime handle when we trigger the `engine.increment_epoch()` above. let task = Arc::new(gpui_tokio::Tokio::spawn(cx, extension_task)?); Ok(WasmExtension {