about summary refs log tree commit diff
path: root/compiler/rustc_driver_impl/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-09-07 04:16:06 +0000
committerMichael Goulet <michael@errs.io>2023-09-07 04:16:06 +0000
commit8ad23794077b4380da05fc5dabb573f38bdb2718 (patch)
tree6bd668e7eb21ca1ad241f1158b59bacc5807f8c0 /compiler/rustc_driver_impl/src
parentf00c1399987c60b4e884afc42f4aa6226855e9ae (diff)
downloadrust-8ad23794077b4380da05fc5dabb573f38bdb2718.tar.gz
rust-8ad23794077b4380da05fc5dabb573f38bdb2718.zip
Don't modify libstd to dump rustc ICEs
Diffstat (limited to 'compiler/rustc_driver_impl/src')
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs63
1 files changed, 37 insertions, 26 deletions
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 1a16759d7f9..35f4ff7d964 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -7,7 +7,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(lazy_cell)]
 #![feature(decl_macro)]
-#![feature(ice_to_disk)]
+#![feature(panic_update_hook)]
 #![feature(let_chains)]
 #![recursion_limit = "256"]
 #![allow(rustc::potential_query_instability)]
@@ -50,9 +50,9 @@ use std::collections::BTreeMap;
 use std::env;
 use std::ffi::OsString;
 use std::fmt::Write as _;
-use std::fs;
+use std::fs::{self, File};
 use std::io::{self, IsTerminal, Read, Write};
-use std::panic::{self, catch_unwind};
+use std::panic::{self, catch_unwind, PanicInfo};
 use std::path::PathBuf;
 use std::process::{self, Command, Stdio};
 use std::str;
@@ -1323,31 +1323,42 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
         std::env::set_var("RUST_BACKTRACE", "full");
     }
 
-    panic::set_hook(Box::new(move |info| {
-        // If the error was caused by a broken pipe then this is not a bug.
-        // Write the error and return immediately. See #98700.
-        #[cfg(windows)]
-        if let Some(msg) = info.payload().downcast_ref::<String>() {
-            if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") {
-                // the error code is already going to be reported when the panic unwinds up the stack
-                let handler = EarlyErrorHandler::new(ErrorOutputType::default());
-                let _ = handler.early_error_no_abort(msg.clone());
-                return;
-            }
-        };
-
-        // Invoke the default handler, which prints the actual panic message and optionally a backtrace
-        // Don't do this for delayed bugs, which already emit their own more useful backtrace.
-        if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
-            std::panic_hook_with_disk_dump(info, ice_path().as_deref());
+    panic::update_hook(Box::new(
+        move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static),
+              info: &PanicInfo<'_>| {
+            // If the error was caused by a broken pipe then this is not a bug.
+            // Write the error and return immediately. See #98700.
+            #[cfg(windows)]
+            if let Some(msg) = info.payload().downcast_ref::<String>() {
+                if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)")
+                {
+                    // the error code is already going to be reported when the panic unwinds up the stack
+                    let handler = EarlyErrorHandler::new(ErrorOutputType::default());
+                    let _ = handler.early_error_no_abort(msg.clone());
+                    return;
+                }
+            };
 
-            // Separate the output with an empty line
-            eprintln!();
-        }
+            // Invoke the default handler, which prints the actual panic message and optionally a backtrace
+            // Don't do this for delayed bugs, which already emit their own more useful backtrace.
+            if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
+                default_hook(info);
+                // Separate the output with an empty line
+                eprintln!();
+
+                if let Some(ice_path) = ice_path()
+                    && let Ok(mut out) =
+                        File::options().create(true).append(true).open(&ice_path)
+                {
+                    let _ =
+                        write!(&mut out, "{info}{:#}", std::backtrace::Backtrace::force_capture());
+                }
+            }
 
-        // Print the ICE message
-        report_ice(info, bug_report_url, extra_info);
-    }));
+            // Print the ICE message
+            report_ice(info, bug_report_url, extra_info);
+        },
+    ));
 }
 
 /// Prints the ICE message, including query stack, but without backtrace.