|
7 | 7 | #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
8 | 8 | #![feature(lazy_cell)]
|
9 | 9 | #![feature(decl_macro)]
|
10 |
| -#![feature(ice_to_disk)] |
| 10 | +#![feature(panic_update_hook)] |
11 | 11 | #![feature(let_chains)]
|
12 | 12 | #![recursion_limit = "256"]
|
13 | 13 | #![allow(rustc::potential_query_instability)]
|
@@ -50,9 +50,9 @@ use std::collections::BTreeMap;
|
50 | 50 | use std::env;
|
51 | 51 | use std::ffi::OsString;
|
52 | 52 | use std::fmt::Write as _;
|
53 |
| -use std::fs; |
| 53 | +use std::fs::{self, File}; |
54 | 54 | use std::io::{self, IsTerminal, Read, Write};
|
55 |
| -use std::panic::{self, catch_unwind}; |
| 55 | +use std::panic::{self, catch_unwind, PanicInfo}; |
56 | 56 | use std::path::PathBuf;
|
57 | 57 | use std::process::{self, Command, Stdio};
|
58 | 58 | use std::str;
|
@@ -1363,31 +1363,59 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&Handler))
|
1363 | 1363 | std::env::set_var("RUST_BACKTRACE", "full");
|
1364 | 1364 | }
|
1365 | 1365 |
|
1366 |
| - panic::set_hook(Box::new(move |info| { |
1367 |
| - // If the error was caused by a broken pipe then this is not a bug. |
1368 |
| - // Write the error and return immediately. See #98700. |
1369 |
| - #[cfg(windows)] |
1370 |
| - if let Some(msg) = info.payload().downcast_ref::<String>() { |
1371 |
| - if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") { |
1372 |
| - // the error code is already going to be reported when the panic unwinds up the stack |
1373 |
| - let handler = EarlyErrorHandler::new(ErrorOutputType::default()); |
1374 |
| - let _ = handler.early_error_no_abort(msg.clone()); |
1375 |
| - return; |
1376 |
| - } |
1377 |
| - }; |
1378 |
| - |
1379 |
| - // Invoke the default handler, which prints the actual panic message and optionally a backtrace |
1380 |
| - // Don't do this for delayed bugs, which already emit their own more useful backtrace. |
1381 |
| - if !info.payload().is::<rustc_errors::DelayedBugPanic>() { |
1382 |
| - std::panic_hook_with_disk_dump(info, ice_path().as_deref()); |
| 1366 | + panic::update_hook(Box::new( |
| 1367 | + move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), |
| 1368 | + info: &PanicInfo<'_>| { |
| 1369 | + // If the error was caused by a broken pipe then this is not a bug. |
| 1370 | + // Write the error and return immediately. See #98700. |
| 1371 | + #[cfg(windows)] |
| 1372 | + if let Some(msg) = info.payload().downcast_ref::<String>() { |
| 1373 | + if msg.starts_with("failed printing to stdout: ") && msg.ends_with("(os error 232)") |
| 1374 | + { |
| 1375 | + // the error code is already going to be reported when the panic unwinds up the stack |
| 1376 | + let handler = EarlyErrorHandler::new(ErrorOutputType::default()); |
| 1377 | + let _ = handler.early_error_no_abort(msg.clone()); |
| 1378 | + return; |
| 1379 | + } |
| 1380 | + }; |
1383 | 1381 |
|
1384 |
| - // Separate the output with an empty line |
1385 |
| - eprintln!(); |
1386 |
| - } |
| 1382 | + // Invoke the default handler, which prints the actual panic message and optionally a backtrace |
| 1383 | + // Don't do this for delayed bugs, which already emit their own more useful backtrace. |
| 1384 | + if !info.payload().is::<rustc_errors::DelayedBugPanic>() { |
| 1385 | + default_hook(info); |
| 1386 | + // Separate the output with an empty line |
| 1387 | + eprintln!(); |
| 1388 | + |
| 1389 | + if let Some(ice_path) = ice_path() |
| 1390 | + && let Ok(mut out) = |
| 1391 | + File::options().create(true).append(true).open(&ice_path) |
| 1392 | + { |
| 1393 | + // The current implementation always returns `Some`. |
| 1394 | + let location = info.location().unwrap(); |
| 1395 | + let msg = match info.payload().downcast_ref::<&'static str>() { |
| 1396 | + Some(s) => *s, |
| 1397 | + None => match info.payload().downcast_ref::<String>() { |
| 1398 | + Some(s) => &s[..], |
| 1399 | + None => "Box<dyn Any>", |
| 1400 | + }, |
| 1401 | + }; |
| 1402 | + let thread = std::thread::current(); |
| 1403 | + let name = thread.name().unwrap_or("<unnamed>"); |
| 1404 | + let _ = write!( |
| 1405 | + &mut out, |
| 1406 | + "thread '{name}' panicked at {location}:\n\ |
| 1407 | + {msg}\n\ |
| 1408 | + stack backtrace:\n\ |
| 1409 | + {:#}", |
| 1410 | + std::backtrace::Backtrace::force_capture() |
| 1411 | + ); |
| 1412 | + } |
| 1413 | + } |
1387 | 1414 |
|
1388 |
| - // Print the ICE message |
1389 |
| - report_ice(info, bug_report_url, extra_info); |
1390 |
| - })); |
| 1415 | + // Print the ICE message |
| 1416 | + report_ice(info, bug_report_url, extra_info); |
| 1417 | + }, |
| 1418 | + )); |
1391 | 1419 | }
|
1392 | 1420 |
|
1393 | 1421 | /// Prints the ICE message, including query stack, but without backtrace.
|
|
0 commit comments