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

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>,