Skip to content

Commit 38a5fee

Browse files
committed
Print a backtrace in const eval if interrupted
1 parent eb9da7b commit 38a5fee

File tree

8 files changed

+45
-7
lines changed

8 files changed

+45
-7
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3413,6 +3413,7 @@ dependencies = [
34133413
name = "rustc_driver_impl"
34143414
version = "0.0.0"
34153415
dependencies = [
3416+
"ctrlc",
34163417
"libc",
34173418
"rustc_ast",
34183419
"rustc_ast_lowering",

Diff for: compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+7-1
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() {

Diff for: compiler/rustc_data_structures/src/lib.rs

+7
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);

Diff for: compiler/rustc_driver_impl/Cargo.toml

+1
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" }

Diff for: compiler/rustc_driver_impl/src/lib.rs

+15
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

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

Diff for: compiler/rustc_middle/src/mir/interpret/error.rs

+3
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
}

Diff for: src/tools/miri/src/concurrency/thread.rs

+8-6
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;
@@ -1013,21 +1014,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10131014
/// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program
10141015
/// termination).
10151016
fn run_threads(&mut self) -> InterpResult<'tcx, !> {
1016-
static SIGNALED: AtomicBool = AtomicBool::new(false);
1017+
// In normal rustc, rustc_driver::main installs this handler. But we don't use that
1018+
// function, see src/bin/miri.rs.
10171019
ctrlc::set_handler(move || {
1018-
// Indicate that we have ben signaled to stop. If we were already signaled, exit
1020+
// Indicate that we have been signaled to stop. If we were already signaled, exit
10191021
// immediately. In our interpreter loop we try to consult this value often, but if for
10201022
// whatever reason we don't get to that check or the cleanup we do upon finding that
10211023
// this bool has become true takes a long time, the exit here will promptly exit the
10221024
// process on the second Ctrl-C.
1023-
if SIGNALED.swap(true, Relaxed) {
1025+
if CTRL_C_RECEIVED.swap(true, Relaxed) {
10241026
std::process::exit(1);
10251027
}
10261028
})
1027-
.unwrap();
1029+
.expect("Unable to install ctrlc handler");
10281030
let this = self.eval_context_mut();
10291031
loop {
1030-
if SIGNALED.load(Relaxed) {
1032+
if CTRL_C_RECEIVED.load(Relaxed) {
10311033
this.machine.handle_abnormal_termination();
10321034
std::process::exit(1);
10331035
}

Diff for: src/tools/tidy/src/deps.rs

+3
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
134134
"crossbeam-utils",
135135
"crypto-common",
136136
"cstr",
137+
"ctrlc",
137138
"datafrog",
138139
"derive_more",
139140
"digest",
@@ -185,6 +186,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
185186
"memmap2",
186187
"memoffset",
187188
"miniz_oxide",
189+
"nix",
188190
"num_cpus",
189191
"object",
190192
"odht",
@@ -281,6 +283,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
281283
"winapi-util",
282284
"winapi-x86_64-pc-windows-gnu",
283285
"windows",
286+
"windows-sys",
284287
"windows-targets",
285288
"windows_aarch64_gnullvm",
286289
"windows_aarch64_msvc",

0 commit comments

Comments
 (0)