mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
crashes: Avoid crash handler on detached threads (#40883)
Set a TLS bit to skip invoking the crash handler when a detached thread panics. cc @P1n3appl3 - is this at odds with what we need the crash handler to do? May close #39289, cannot repro without a nightly build Release Notes: - Fixed extension panics crashing Zed on Linux Co-authored-by: dino <dinojoaocosta@gmail.com>
This commit is contained in:
parent
1ce9a85a1a
commit
68707ffc74
5 changed files with 31 additions and 12 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -4132,6 +4132,7 @@ dependencies = [
|
|||
"bincode 1.3.3",
|
||||
"cfg-if",
|
||||
"crash-handler",
|
||||
"extension_host",
|
||||
"log",
|
||||
"mach2 0.5.0",
|
||||
"minidumper",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ license = "GPL-3.0-or-later"
|
|||
bincode.workspace = true
|
||||
cfg-if.workspace = true
|
||||
crash-handler.workspace = true
|
||||
extension_host.workspace = true
|
||||
log.workspace = true
|
||||
minidumper.workspace = true
|
||||
paths.workspace = true
|
||||
|
|
|
|||
|
|
@ -286,6 +286,11 @@ 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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let message = info
|
||||
.payload()
|
||||
.downcast_ref::<&str>()
|
||||
|
|
|
|||
|
|
@ -30,12 +30,14 @@ use node_runtime::NodeRuntime;
|
|||
use release_channel::ReleaseChannel;
|
||||
use semantic_version::SemanticVersion;
|
||||
use settings::Settings;
|
||||
use std::borrow::Cow;
|
||||
use std::sync::{LazyLock, OnceLock};
|
||||
use std::time::Duration;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
sync::{
|
||||
Arc, LazyLock, OnceLock,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
use task::{DebugScenario, SpawnInTerminal, TaskTemplate, ZedDebugConfig};
|
||||
use util::paths::SanitizedPath;
|
||||
|
|
@ -495,6 +497,11 @@ pub struct WasmState {
|
|||
pub(crate) capability_granter: CapabilityGranter,
|
||||
}
|
||||
|
||||
std::thread_local! {
|
||||
/// Used by the crash handler to ignore panics in extension-related threads.
|
||||
pub static IS_WASM_THREAD: AtomicBool = const { AtomicBool::new(false) };
|
||||
}
|
||||
|
||||
type MainThreadCall = Box<dyn Send + for<'a> FnOnce(&'a mut AsyncApp) -> LocalBoxFuture<'a, ()>>;
|
||||
|
||||
type ExtensionCall = Box<
|
||||
|
|
@ -529,6 +536,7 @@ 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`.
|
||||
|
|
|
|||
|
|
@ -2,21 +2,20 @@ use crate::{App, PlatformDispatcher};
|
|||
use async_task::Runnable;
|
||||
use futures::channel::mpsc;
|
||||
use smol::prelude::*;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::panic::Location;
|
||||
use std::thread::{self, ThreadId};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
mem::{self, ManuallyDrop},
|
||||
num::NonZeroUsize,
|
||||
panic::Location,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicUsize, Ordering::SeqCst},
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
},
|
||||
task::{Context, Poll},
|
||||
thread::{self, ThreadId},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use util::TryFutureExt;
|
||||
|
|
@ -123,7 +122,12 @@ impl TaskLabel {
|
|||
/// Construct a new task label.
|
||||
pub fn new() -> Self {
|
||||
static NEXT_TASK_LABEL: AtomicUsize = AtomicUsize::new(1);
|
||||
Self(NEXT_TASK_LABEL.fetch_add(1, SeqCst).try_into().unwrap())
|
||||
Self(
|
||||
NEXT_TASK_LABEL
|
||||
.fetch_add(1, Ordering::SeqCst)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +275,7 @@ impl BackgroundExecutor {
|
|||
let awoken = awoken.clone();
|
||||
let unparker = unparker.clone();
|
||||
move || {
|
||||
awoken.store(true, SeqCst);
|
||||
awoken.store(true, Ordering::SeqCst);
|
||||
unparker.unpark();
|
||||
}
|
||||
});
|
||||
|
|
@ -287,7 +291,7 @@ impl BackgroundExecutor {
|
|||
max_ticks -= 1;
|
||||
|
||||
if !dispatcher.tick(background_only) {
|
||||
if awoken.swap(false, SeqCst) {
|
||||
if awoken.swap(false, Ordering::SeqCst) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue