authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-03 14:25:27-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-03 15:20:12-07:00
log26d313ff895bef3a6121acee7d27aaa42b494384
tree15ead0ee403f12c291997c75291fc941d2bf14a6
parent2fbbd55d139b80699e548bc1014aeef2c714bdbc
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU

chore: release builds abort on a panic instead of unwinding

The panic hook still logs the backtrace from the unwind tables, which stay. On Windows the hook shows the stopped alert itself, as no catch_unwind outlives the abort, and x86_64's std is built with panic_abort beside panic_unwind. Release executables after the debug split: Linux x86_64 47.08 to 42.15 MB (-4.92), macOS aarch64 34.17 to 29.37 MB (-4.80), Windows x86_64 37.28 to 33.90 MB (-3.38). Linux keeps 1.14 MB of .eh_frame; landing pads and their tables go. Assisted-by: claude-opus-5.5

3 files changed, 24 insertions(+), 21 deletions(-)

Cargo.toml+1
......@@ -16,6 +16,7 @@ sctk-adwaita = { path = "vendor/sctk-adwaita" }
1616[profile.release]
1717lto = "fat"
1818codegen-units = 1
19panic = "abort"
1920
2021# Code that runs at a person's pace, not a frame's: system services, the network, file and
2122# image formats, shader translation.
crates/snowbound/src/windows.rs+22-20
......@@ -935,42 +935,44 @@ pub fn cover_border_line(_: &mut Ui, _: f32) {}
935935pub fn with_pool(
936936 run: impl FnOnce() -> Result<(), Box<dyn std::error::Error>>,
937937) -> Result<(), Box<dyn std::error::Error>> {
938 use std::panic;
939 let log = log_stderr();
938 let details = log_stderr().map(|log| format!("The log is at {}.", log.display()));
940939 let (major, minor, build) = version();
941940 eprintln!(
942941 "Snowbound {} on Windows {major}.{minor}.{build}",
943942 option_env!("SNOWBOUND_BUILD").unwrap_or("development")
944943 );
945 panic::set_hook(Box::new(|info| {
944 let shown = details.clone();
945 std::panic::set_hook(Box::new(move |info| {
946946 let thread = std::thread::current();
947947 let backtrace = std::backtrace::Backtrace::force_capture();
948948 eprintln!(
949949 "Thread {:?} {info}\n{backtrace}",
950950 thread.name().unwrap_or("")
951951 );
952 // The panic aborts the process once this returns, taking an alert's thread with it.
953 if cfg!(panic = "abort")
954 && let Some(details) = &shown
955 {
956 let text = wide(format!(
957 "Snowbound stopped because of a problem.\n\n{details}"
958 ));
959 let caption = wide("Snowbound");
960 let style = wm::MB_OK | wm::MB_ICONWARNING;
961 unsafe {
962 wm::MessageBoxW(std::ptr::null_mut(), text.as_ptr(), caption.as_ptr(), style)
963 };
964 }
952965 }));
953966 unsafe {
954967 windows_sys::Win32::System::Diagnostics::Debug::AddVectoredExceptionHandler(0, Some(fault))
955968 };
956 let result = panic::catch_unwind(panic::AssertUnwindSafe(run));
957 let Some(log) = log else {
958 return result.unwrap_or_else(|payload| panic::resume_unwind(payload));
959 };
960 let details = format!("The log is at {}.", log.display());
961 // The window is gone, and a message box it owned wouldn't show.
962 WINDOW.store(0, Ordering::Relaxed);
963 match result {
964 Ok(Err(error)) => {
965 alert(&error.to_string(), &details);
966 Err(error)
967 }
968 Ok(done) => done,
969 Err(payload) => {
970 alert("Snowbound stopped because of a problem.", &details);
971 panic::resume_unwind(payload)
972 }
969 let result = run();
970 if let (Err(error), Some(details)) = (&result, details) {
971 // The window is gone, and a message box it owned wouldn't show.
972 WINDOW.store(0, Ordering::Relaxed);
973 alert(&error.to_string(), &details);
973974 }
975 result
974976}
975977
976978/// Points stderr at `snowbound.log` in the cache folder where it goes nowhere, keeping the
platform/windows/cargo.sh+1-1
......@@ -22,7 +22,7 @@ x86_64)
2222 # raw-dylib imports (the windows crates) are made by llvm-mingw's dlltool. Cargo
2323 # can't see link.sh's inputs; folding their hash into the flags relinks on change.
2424 runtime=$(cat "$here/link.sh" "$here"/rt/* | shasum | cut -c1-12)
25 set -- -Zbuild-std=std,panic_unwind \
25 set -- -Zbuild-std=std,panic_abort,panic_unwind \
2626 --config "target.$target.linker='$here/link.sh'" \
2727 --config "target.$target.rustflags=['-C','linker-flavor=gcc','-C','metadata=rt-$runtime','-C','dlltool=$LLVM_MINGW/bin/x86_64-w64-mingw32-dlltool']" "$@"
2828 ;;