Skip to content

Commit 6661426

Browse files
authored
Rollup merge of #111769 - saethlin:ctfe-backtrace-ctrlc, r=RalfJung
Print a backtrace in const eval if interrupted Demo: ```rust #![feature(const_eval_limit)] #![const_eval_limit = "0"] const OW: u64 = { let mut res: u64 = 0; let mut i = 0; while i < u64::MAX { res = res.wrapping_add(i); i += 1; } res }; fn main() { println!("{}", OW); } ``` ``` ╭ ➜ ben@archlinux:~/rust ╰ ➤ rustc +stage1 spin.rs ^Cerror[E0080]: evaluation of constant value failed --> spin.rs:8:33 | 8 | res = res.wrapping_add(i); | ^ Compilation was interrupted note: erroneous constant used --> spin.rs:15:20 | 15 | println!("{}", OW); | ^^ note: erroneous constant used --> spin.rs:15:20 | 15 | println!("{}", OW); | ^^ | = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. ```
2 parents 983148a + 38a5fee commit 6661426

File tree

8 files changed

+45
-7
lines changed

8 files changed

+45
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,6 +3319,7 @@ dependencies = [
33193319
name = "rustc_driver_impl"
33203320
version = "0.0.0"
33213321
dependencies = [
3322+
"ctrlc",
33223323
"libc",
33233324
"rustc_ast",
33243325
"rustc_ast_lowering",

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use crate::const_eval::CheckAlignment;
22
use std::borrow::Cow;
3+
use std::sync::atomic::Ordering::Relaxed;
34

45
use either::{Left, Right};
56

7+
use rustc_data_structures::CTRL_C_RECEIVED;
68
use rustc_hir::def::DefKind;
79
use rustc_middle::mir;
810
use rustc_middle::mir::interpret::ErrorHandled;
@@ -66,7 +68,11 @@ fn eval_body_using_ecx<'mir, 'tcx>(
6668
)?;
6769

6870
// The main interpreter loop.
69-
while ecx.step()? {}
71+
while ecx.step()? {
72+
if CTRL_C_RECEIVED.load(Relaxed) {
73+
throw_exhaust!(Interrupted);
74+
}
75+
}
7076

7177
// Intern the result
7278
let intern_kind = if cid.promoted.is_some() {

compiler/rustc_data_structures/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ extern crate cfg_if;
4646
#[macro_use]
4747
extern crate rustc_macros;
4848

49+
use std::sync::atomic::AtomicBool;
50+
4951
pub use rustc_index::static_assert_size;
5052

5153
#[inline(never)]
@@ -129,3 +131,8 @@ impl<F: FnOnce()> Drop for OnDrop<F> {
129131
// See comments in src/librustc_middle/lib.rs
130132
#[doc(hidden)]
131133
pub fn __noop_fix_for_27438() {}
134+
135+
/// `rustc_driver::main` installs a handler that will set this to `true` if
136+
/// the compiler has been sent a request to shut down, such as by a Ctrl-C.
137+
/// This static is placed here so that it is available to all parts of the compiler.
138+
pub static CTRL_C_RECEIVED: AtomicBool = AtomicBool::new(false);

compiler/rustc_driver_impl/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
[lib]
77

88
[dependencies]
9+
ctrlc = "3.3.0"
910
tracing = { version = "0.1.35" }
1011
serde_json = "1.0.59"
1112
rustc_log = { path = "../rustc_log" }

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_data_structures::profiling::{
2323
get_resident_set_size, print_time_passes_entry, TimePassesFormat,
2424
};
2525
use rustc_data_structures::sync::SeqCst;
26+
use rustc_data_structures::CTRL_C_RECEIVED;
2627
use rustc_errors::registry::{InvalidErrorCode, Registry};
2728
use rustc_errors::{
2829
DiagnosticMessage, ErrorGuaranteed, Handler, PResult, SubdiagnosticMessage, TerminalUrl,
@@ -55,6 +56,7 @@ use std::panic::{self, catch_unwind};
5556
use std::path::PathBuf;
5657
use std::process::{self, Command, Stdio};
5758
use std::str;
59+
use std::sync::atomic::Ordering::Relaxed;
5860
use std::sync::OnceLock;
5961
use std::time::Instant;
6062

@@ -1410,6 +1412,19 @@ pub fn main() -> ! {
14101412
signal_handler::install();
14111413
let mut callbacks = TimePassesCallbacks::default();
14121414
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
1415+
1416+
ctrlc::set_handler(move || {
1417+
// Indicate that we have been signaled to stop. If we were already signaled, exit
1418+
// immediately. In our interpreter loop we try to consult this value often, but if for
1419+
// whatever reason we don't get to that check or the cleanup we do upon finding that
1420+
// this bool has become true takes a long time, the exit here will promptly exit the
1421+
// process on the second Ctrl-C.
1422+
if CTRL_C_RECEIVED.swap(true, Relaxed) {
1423+
std::process::exit(1);
1424+
}
1425+
})
1426+
.expect("Unable to install ctrlc handler");
1427+
14131428
let exit_code = catch_with_exit_code(|| {
14141429
let args = env::args_os()
14151430
.enumerate()

compiler/rustc_middle/src/mir/interpret/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ pub enum ResourceExhaustionInfo {
473473
MemoryExhausted,
474474
/// The address space (of the target) is full.
475475
AddressSpaceFull,
476+
/// The compiler got an interrupt signal (a user ran out of patience).
477+
Interrupted,
476478
}
477479

478480
impl fmt::Display for ResourceExhaustionInfo {
@@ -491,6 +493,7 @@ impl fmt::Display for ResourceExhaustionInfo {
491493
AddressSpaceFull => {
492494
write!(f, "there are no more free addresses in the address space")
493495
}
496+
Interrupted => write!(f, "compilation was interrupted"),
494497
}
495498
}
496499
}

src/tools/miri/src/concurrency/thread.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
use std::cell::RefCell;
44
use std::collections::hash_map::Entry;
55
use std::num::TryFromIntError;
6-
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
6+
use std::sync::atomic::Ordering::Relaxed;
77
use std::task::Poll;
88
use std::time::{Duration, SystemTime};
99

1010
use log::trace;
1111

1212
use rustc_data_structures::fx::FxHashMap;
13+
use rustc_data_structures::CTRL_C_RECEIVED;
1314
use rustc_hir::def_id::DefId;
1415
use rustc_index::{Idx, IndexVec};
1516
use rustc_middle::mir::Mutability;
@@ -1020,21 +1021,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10201021
/// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program
10211022
/// termination).
10221023
fn run_threads(&mut self) -> InterpResult<'tcx, !> {
1023-
static SIGNALED: AtomicBool = AtomicBool::new(false);
1024+
// In normal rustc, rustc_driver::main installs this handler. But we don't use that
1025+
// function, see src/bin/miri.rs.
10241026
ctrlc::set_handler(move || {
1025-
// Indicate that we have ben signaled to stop. If we were already signaled, exit
1027+
// Indicate that we have been signaled to stop. If we were already signaled, exit
10261028
// immediately. In our interpreter loop we try to consult this value often, but if for
10271029
// whatever reason we don't get to that check or the cleanup we do upon finding that
10281030
// this bool has become true takes a long time, the exit here will promptly exit the
10291031
// process on the second Ctrl-C.
1030-
if SIGNALED.swap(true, Relaxed) {
1032+
if CTRL_C_RECEIVED.swap(true, Relaxed) {
10311033
std::process::exit(1);
10321034
}
10331035
})
1034-
.unwrap();
1036+
.expect("Unable to install ctrlc handler");
10351037
let this = self.eval_context_mut();
10361038
loop {
1037-
if SIGNALED.load(Relaxed) {
1039+
if CTRL_C_RECEIVED.load(Relaxed) {
10381040
this.machine.handle_abnormal_termination();
10391041
std::process::exit(1);
10401042
}

src/tools/tidy/src/deps.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
133133
"crossbeam-utils",
134134
"crypto-common",
135135
"cstr",
136+
"ctrlc",
136137
"datafrog",
137138
"derive_more",
138139
"digest",
@@ -184,6 +185,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
184185
"memmap2",
185186
"memoffset",
186187
"miniz_oxide",
188+
"nix",
187189
"num_cpus",
188190
"object",
189191
"odht",
@@ -280,6 +282,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
280282
"winapi-util",
281283
"winapi-x86_64-pc-windows-gnu",
282284
"windows",
285+
"windows-sys",
283286
"windows-targets",
284287
"windows_aarch64_gnullvm",
285288
"windows_aarch64_msvc",

0 commit comments

Comments
 (0)