Skip to content

Commit 28da09d

Browse files
authored
Rollup merge of rust-lang#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 2a1af89 + 372f91b commit 28da09d

File tree

10 files changed

+50
-13
lines changed

10 files changed

+50
-13
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -809,9 +809,9 @@ dependencies = [
809809

810810
[[package]]
811811
name = "ctrlc"
812-
version = "3.4.0"
812+
version = "3.4.1"
813813
source = "registry+https://github.com/rust-lang/crates.io-index"
814-
checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e"
814+
checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf"
815815
dependencies = [
816816
"nix",
817817
"windows-sys 0.48.0",
@@ -2410,14 +2410,13 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
24102410

24112411
[[package]]
24122412
name = "nix"
2413-
version = "0.26.2"
2413+
version = "0.27.1"
24142414
source = "registry+https://github.com/rust-lang/crates.io-index"
2415-
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
2415+
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
24162416
dependencies = [
2417-
"bitflags 1.3.2",
2417+
"bitflags 2.3.3",
24182418
"cfg-if",
24192419
"libc",
2420-
"static_assertions",
24212420
]
24222421

24232422
[[package]]
@@ -3552,6 +3551,7 @@ dependencies = [
35523551
name = "rustc_driver_impl"
35533552
version = "0.0.0"
35543553
dependencies = [
3554+
"ctrlc",
35553555
"libc",
35563556
"rustc_ast",
35573557
"rustc_ast_lowering",

compiler/rustc_const_eval/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ const_eval_interior_mutable_data_refer =
134134
This would make multiple uses of a constant to be able to see different values and allow circumventing
135135
the `Send` and `Sync` requirements for shared mutable data, which is unsound.
136136
137+
const_eval_interrupted = compilation was interrupted
138+
137139
const_eval_invalid_align =
138140
align has to be a power of 2
139141

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 crate::errors::ConstEvalError;
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, InterpErrorInfo};
@@ -64,7 +66,11 @@ fn eval_body_using_ecx<'mir, 'tcx>(
6466
ecx.storage_live_for_always_live_locals()?;
6567

6668
// The main interpreter loop.
67-
while ecx.step()? {}
69+
while ecx.step()? {
70+
if CTRL_C_RECEIVED.load(Relaxed) {
71+
throw_exhaust!(Interrupted);
72+
}
73+
}
6874

6975
// Intern the result
7076
let intern_kind = if cid.promoted.is_some() {

compiler/rustc_const_eval/src/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
901901
ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached,
902902
ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted,
903903
ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
904+
ResourceExhaustionInfo::Interrupted => const_eval_interrupted,
904905
}
905906
}
906907
fn add_args<G: EmissionGuarantee>(self, _: &Handler, _: &mut DiagnosticBuilder<'_, G>) {}

compiler/rustc_data_structures/src/lib.rs

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

50+
use std::sync::atomic::AtomicBool;
51+
5052
pub use rustc_index::static_assert_size;
5153

5254
#[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
@@ -7,6 +7,7 @@ edition = "2021"
77

88
[dependencies]
99
time = { version = "0.3", default-features = false, features = ["formatting", ] }
10+
ctrlc = "3.4.1"
1011
tracing = { version = "0.1.35" }
1112
serde_json = "1.0.59"
1213
rustc_log = { path = "../rustc_log" }

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_data_structures::profiling::{
2525
get_resident_set_size, print_time_passes_entry, TimePassesFormat,
2626
};
2727
use rustc_data_structures::sync::SeqCst;
28+
use rustc_data_structures::CTRL_C_RECEIVED;
2829
use rustc_errors::registry::{InvalidErrorCode, Registry};
2930
use rustc_errors::{markdown, ColorConfig};
3031
use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, PResult, SubdiagnosticMessage};
@@ -1459,6 +1460,19 @@ pub fn main() -> ! {
14591460
signal_handler::install();
14601461
let mut callbacks = TimePassesCallbacks::default();
14611462
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
1463+
1464+
ctrlc::set_handler(move || {
1465+
// Indicate that we have been signaled to stop. If we were already signaled, exit
1466+
// immediately. In our interpreter loop we try to consult this value often, but if for
1467+
// whatever reason we don't get to that check or the cleanup we do upon finding that
1468+
// this bool has become true takes a long time, the exit here will promptly exit the
1469+
// process on the second Ctrl-C.
1470+
if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) {
1471+
std::process::exit(1);
1472+
}
1473+
})
1474+
.expect("Unable to install ctrlc handler");
1475+
14621476
let exit_code = catch_with_exit_code(|| {
14631477
let args = env::args_os()
14641478
.enumerate()

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ pub enum ResourceExhaustionInfo {
444444
MemoryExhausted,
445445
/// The address space (of the target) is full.
446446
AddressSpaceFull,
447+
/// The compiler got an interrupt signal (a user ran out of patience).
448+
Interrupted,
447449
}
448450

449451
/// A trait for machine-specific errors (or other "machine stop" conditions).

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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
137137
"crossbeam-utils",
138138
"crypto-common",
139139
"cstr",
140+
"ctrlc",
140141
"darling",
141142
"darling_core",
142143
"darling_macro",
@@ -198,6 +199,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
198199
"memmap2",
199200
"memoffset",
200201
"miniz_oxide",
202+
"nix",
201203
"nu-ansi-term",
202204
"num_cpus",
203205
"object",

0 commit comments

Comments
 (0)