Suspend macOS threads during crashes (#36520)

This should improve our detection of which thread crashed since they
wont be able to resume while the minidump is being generated.

Release Notes:

- N/A
This commit is contained in:
Julia Ryan 2025-08-19 16:31:13 -05:00 committed by GitHub
parent 5fb68cb8be
commit 88c4a5ca49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 5 deletions

20
Cargo.lock generated
View file

@ -3872,7 +3872,7 @@ dependencies = [
"jni",
"js-sys",
"libc",
"mach2",
"mach2 0.4.2",
"ndk",
"ndk-context",
"num-derive",
@ -4022,7 +4022,7 @@ checksum = "031ed29858d90cfdf27fe49fae28028a1f20466db97962fa2f4ea34809aeebf3"
dependencies = [
"cfg-if",
"libc",
"mach2",
"mach2 0.4.2",
]
[[package]]
@ -4034,7 +4034,7 @@ dependencies = [
"cfg-if",
"crash-context",
"libc",
"mach2",
"mach2 0.4.2",
"parking_lot",
]
@ -4044,6 +4044,7 @@ version = "0.1.0"
dependencies = [
"crash-handler",
"log",
"mach2 0.5.0",
"minidumper",
"paths",
"release_channel",
@ -9866,6 +9867,15 @@ dependencies = [
"libc",
]
[[package]]
name = "mach2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a1b95cd5421ec55b445b5ae102f5ea0e768de1f82bd3001e11f426c269c3aea"
dependencies = [
"libc",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
@ -10202,7 +10212,7 @@ dependencies = [
"goblin",
"libc",
"log",
"mach2",
"mach2 0.4.2",
"memmap2",
"memoffset",
"minidump-common",
@ -18292,7 +18302,7 @@ dependencies = [
"indexmap",
"libc",
"log",
"mach2",
"mach2 0.4.2",
"memfd",
"object",
"once_cell",

View file

@ -515,6 +515,7 @@ libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
linkify = "0.10.0"
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
lsp-types = { git = "https://github.com/zed-industries/lsp-types", rev = "39f629bdd03d59abd786ed9fc27e8bca02c0c0ec" }
mach2 = "0.5"
markup5ever_rcdom = "0.3.0"
metal = "0.29"
minidumper = "0.8"

View file

@ -16,6 +16,9 @@ serde.workspace = true
serde_json.workspace = true
workspace-hack.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
mach2.workspace = true
[lints]
workspace = true

View file

@ -74,6 +74,9 @@ pub async fn init(crash_init: InitCrashHandler) {
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
.is_ok()
{
#[cfg(target_os = "macos")]
suspend_all_other_threads();
client.ping().unwrap();
client.request_dump(crash_context).is_ok()
} else {
@ -98,6 +101,23 @@ pub async fn init(crash_init: InitCrashHandler) {
}
}
#[cfg(target_os = "macos")]
unsafe fn suspend_all_other_threads() {
let task = unsafe { mach2::traps::current_task() };
let mut threads: mach2::mach_types::thread_act_array_t = std::ptr::null_mut();
let mut count = 0;
unsafe {
mach2::task::task_threads(task, &raw mut threads, &raw mut count);
}
let current = unsafe { mach2::mach_init::mach_thread_self() };
for i in 0..count {
let t = unsafe { *threads.add(i as usize) };
if t != current {
unsafe { mach2::thread_act::thread_suspend(t) };
}
}
}
pub struct CrashServer {
initialization_params: OnceLock<InitCrashHandler>,
panic_info: OnceLock<CrashPanic>,