feat(diag): leave a crash report behind when the app panics

A release build hides the console and is stripped, so a panic ended the
process with nothing on screen, nothing on stderr and nothing on disk.
The window simply disappeared. That is all a reporter has ever had to
work from, which is why #635 and #845 ask for crash logs and why a
crash like #830 can be reported for months with no detail beyond the
steps to reach it.

Every panic now writes one file to <config>/crash_logs naming the
version, the OS, the graphics backend that was live, the thread, the
panic message, the source location and a backtrace. The hook chains
onto whatever was installed before it, so a debug build still prints to
stderr as well, and it is installed after the child-process handoffs:
a GPU probe aborting is how an unusable backend gets detected, not a
crash worth filing.

The report is written by a plain function taking the message and
location, so the layout is covered by tests without installing a panic
hook -- a test that asserts inside a hook fires on every other test's
panic and aborts the whole binary, which is how the first version of
these tests failed.

Backtraces use `force_capture`, not `capture`: a report that says
"disabled backtrace" because the user never set RUST_BACKTRACE is
exactly the report that helps nobody.

The text is deliberately English and does not go through `t!`. It is
read by whoever receives the bug report, and a panic handler that calls
into the localisation machinery risks a second panic while handling the
first.

Confirmed on Windows 11 by reproducing a real crash: opening either of
two large drawings on an Intel Iris Xe dies inside wgpu, and the report
names it -- "Buffer with '(wgpu internal) StagingBelt staging buffer'
label is invalid", backend dx12, with the full frame list.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
mechpanosandClaude Opus 5 committed 2026-09-28 17:13:28 +03:00
1 parent d40e6c8d1d
commit 55f62cc2e3
2 files changed
+177

No files matched your search

+7
View File
@@ -75,6 +75,13 @@ fn main() -> iced::Result {
return Ok(());
}
// Crash log. A release build hides the console, so before this a
// panic ended the process with nothing on screen and nothing on disk
// (#635, #845). Installed after the child-process handoffs above: a
// GPU probe aborting is how an unusable backend is detected, not a
// crash worth filing.
OpenCADStudio::sys::crash_log::install();
// Opt-in logging. `--log LEVEL` seeds RUST_LOG; the subscriber then
// surfaces wgpu / iced / winit diagnostics that are otherwise silent.
if let Some(level) = &args.log {