From 3beec5ce71d34ca8bf51195b74d67f1bff56c675 Mon Sep 17 00:00:00 2001 From: Sorin Albu-Irimies Date: Sat, 7 Nov 2026 16:14:32 +0100 Subject: [PATCH] fix(codegen): don't double-panic when dumping the module on ICE `DumpModuleOnPanic::drop` runs while already unwinding. `dump_module` unwrapped its file I/O, so a failed write panicked again, aborting the process and losing the original ICE message. It now returns `io::Result` and the error is logged. --- crates/rustc_codegen_spirv/src/builder_spirv.rs | 12 ++++++------ crates/rustc_codegen_spirv/src/lib.rs | 6 +++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder_spirv.rs b/crates/rustc_codegen_spirv/src/builder_spirv.rs index c6ee3114293..7caf9e5424b 100644 --- a/crates/rustc_codegen_spirv/src/builder_spirv.rs +++ b/crates/rustc_codegen_spirv/src/builder_spirv.rs @@ -27,7 +27,7 @@ use std::hash::{Hash, Hasher}; use std::iter; use std::ops::Range; use std::sync::Arc; -use std::{fs::File, io::Write, path::Path}; +use std::{fs, io, path::Path}; #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)] pub enum SpirvValueKind { @@ -498,12 +498,12 @@ impl<'tcx> BuilderSpirv<'tcx> { } /// Helper function useful to place right before a crash, to debug the module state. - pub fn dump_module(&self, path: impl AsRef) { + /// + /// Returns an error instead of panicking, as it's typically called while + /// already panicking (where a second panic would abort the process). + pub fn dump_module(&self, path: impl AsRef) -> io::Result<()> { let module = self.builder.borrow().module_ref().assemble(); - File::create(path) - .unwrap() - .write_all(spirv_tools::binary::from_binary(&module)) - .unwrap(); + fs::write(path, spirv_tools::binary::from_binary(&module)) } /// See comment on `BuilderCursor` diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 3e77dbc81c1..c4039a0d098 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -510,7 +510,11 @@ impl Drop for DumpModuleOnPanic<'_, '_, '_> { fn drop(&mut self) { if std::thread::panicking() { if self.path.has_root() { - self.cx.builder.dump_module(self.path); + // NOTE never panic here: we're already unwinding, and a + // second panic would abort, losing the original panic message. + if let Err(err) = self.cx.builder.dump_module(self.path) { + error!("failed to dump module to `{}`: {err}", self.path.display()); + } } else { error!("{}", self.cx.builder.dump_module_str()); }