servoshell's crash_handler::install() is a no-op on Windows -- every native crash is silent, no console output, no WER event
Describe the bug:
ports/servoshell/crash_handler.rs's install() is a real signal handler on macOS/Linux (catches SIGSEGV/SIGILL/SIGIOT/SIGBUS, prints a backtrace via the existing allocation-free backtrace::print, then re-raises for a core dump) but a complete no-op on Windows:
#[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "android")))]
pub fn install() {}Consequence: every native crash on Windows (a segfault, an access violation, etc.) is completely silent — no console output, and in practice no Windows Error Reporting event either (cause unclear; possibly interacting with how the process terminates). This makes diagnosing any Windows-only crash (see #48109, filed today) much harder than it needs to be, since there's nothing to go on beyond "the process is gone."
Fix used downstream (happy to open a PR against this repo if useful — this is currently only in our fork): implement the Win32 equivalent using SetUnhandledExceptionFilter, reusing the same backtrace::print the Unix handler already calls:
#[cfg(target_os = "windows")]
pub fn install() {
use windows_sys::Win32::System::Diagnostics::Debug::{
EXCEPTION_EXECUTE_HANDLER, EXCEPTION_POINTERS, SetUnhandledExceptionFilter,
};
unsafe extern "system" fn handler(exception_info: *const EXCEPTION_POINTERS) -> i32 {
static BEEN_HERE_BEFORE: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
if !BEEN_HERE_BEFORE.swap(true, std::sync::atomic::Ordering::SeqCst) {
let code = unsafe {
(*exception_info).ExceptionRecord.as_ref().map(|r| r.ExceptionCode).unwrap_or(0)
};
let stderr = std::io::stderr();
let mut stderr = stderr.lock();
let _ = writeln!(&mut stderr, "Caught exception 0x{:X}", code as u32);
let _ = crate::backtrace::print(&mut stderr);
}
EXCEPTION_EXECUTE_HANDLER
}
unsafe { SetUnhandledExceptionFilter(Some(handler)); }
}Needs windows-sys features Win32_System_Diagnostics_Debug and Win32_System_Kernel (the latter for EXCEPTION_POINTERS, which is gated behind it).
Caveat found in practice: the backtrace this produces for an optimized/release crash is heavily symbol-garbled (repeated/misattributed frames) without full PDB coverage for the statically-linked C++ (mozjs) code — still strictly better than nothing, and it did surface real frames (e.g. SpiderMonkey symbols) that pointed the investigation in the right direction for #48109.
Platform: Windows 11.
Source: servo/servo