Skip to content

Commit 372f91b

Browse files
committed
Print a backtrace in const eval if interrupted
1 parent 1bd0430 commit 372f91b

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
@@ -781,9 +781,9 @@ dependencies = [
781781

782782
[[package]]
783783
name = "ctrlc"
784-
version = "3.4.0"
784+
version = "3.4.1"
785785
source = "registry+https://github.com/rust-lang/crates.io-index"
786-
checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e"
786+
checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf"
787787
dependencies = [
788788
"nix",
789789
"windows-sys",
@@ -2357,14 +2357,13 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
23572357

23582358
[[package]]
23592359
name = "nix"
2360-
version = "0.26.2"
2360+
version = "0.27.1"
23612361
source = "registry+https://github.com/rust-lang/crates.io-index"
2362-
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
2362+
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
23632363
dependencies = [
2364-
"bitflags 1.3.2",
2364+
"bitflags 2.3.3",
23652365
"cfg-if",
23662366
"libc",
2367-
"static_assertions",
23682367
]
23692368

23702369
[[package]]
@@ -3468,6 +3467,7 @@ dependencies = [
34683467
name = "rustc_driver_impl"
34693468
version = "0.0.0"
34703469
dependencies = [
3470+
"ctrlc",
34713471
"libc",
34723472
"rustc_ast",
34733473
"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};
@@ -63,7 +65,11 @@ fn eval_body_using_ecx<'mir, 'tcx>(
6365
)?;
6466

6567
// The main interpreter loop.
66-
while ecx.step()? {}
68+
while ecx.step()? {
69+
if CTRL_C_RECEIVED.load(Relaxed) {
70+
throw_exhaust!(Interrupted);
71+
}
72+
}
6773

6874
// Intern the result
6975
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
@@ -900,6 +900,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
900900
ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached,
901901
ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted,
902902
ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
903+
ResourceExhaustionInfo::Interrupted => const_eval_interrupted,
903904
}
904905
}
905906
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};
@@ -1518,6 +1519,19 @@ pub fn main() -> ! {
15181519
signal_handler::install();
15191520
let mut callbacks = TimePassesCallbacks::default();
15201521
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
1522+
1523+
ctrlc::set_handler(move || {
1524+
// Indicate that we have been signaled to stop. If we were already signaled, exit
1525+
// immediately. In our interpreter loop we try to consult this value often, but if for
1526+
// whatever reason we don't get to that check or the cleanup we do upon finding that
1527+
// this bool has become true takes a long time, the exit here will promptly exit the
1528+
// process on the second Ctrl-C.
1529+
if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) {
1530+
std::process::exit(1);
1531+
}
1532+
})
1533+
.expect("Unable to install ctrlc handler");
1534+
15211535
let exit_code = catch_with_exit_code(|| {
15221536
let args = env::args_os()
15231537
.enumerate()

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ pub enum ResourceExhaustionInfo {
442442
MemoryExhausted,
443443
/// The address space (of the target) is full.
444444
AddressSpaceFull,
445+
/// The compiler got an interrupt signal (a user ran out of patience).
446+
Interrupted,
445447
}
446448

447449
/// 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)