Skip to content

Commit

Permalink
Print a backtrace in const eval if interrupted
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Mar 10, 2024
1 parent cdb775c commit f7bf976
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 14 deletions.
18 changes: 13 additions & 5 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,12 @@ dependencies = [
"rustc-std-workspace-core",
]

[[package]]
name = "cfg_aliases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"

[[package]]
name = "chrono"
version = "0.4.34"
Expand Down Expand Up @@ -884,9 +890,9 @@ dependencies = [

[[package]]
name = "ctrlc"
version = "3.4.2"
version = "3.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b"
checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345"
dependencies = [
"nix",
"windows-sys 0.52.0",
Expand Down Expand Up @@ -2193,7 +2199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2caa5afb8bf9f3a2652760ce7d4f62d21c4d5a423e68466fca30df82f2330164"
dependencies = [
"cfg-if",
"windows-targets 0.52.4",
"windows-targets 0.48.5",
]

[[package]]
Expand Down Expand Up @@ -2519,12 +2525,13 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"

[[package]]
name = "nix"
version = "0.27.1"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags 2.4.2",
"cfg-if",
"cfg_aliases",
"libc",
]

Expand Down Expand Up @@ -3744,6 +3751,7 @@ dependencies = [
name = "rustc_driver_impl"
version = "0.0.0"
dependencies = [
"ctrlc",
"libc",
"rustc_ast",
"rustc_ast_lowering",
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ const_eval_intern_kind = {$kind ->
*[other] {""}
}
const_eval_interrupted = compilation was interrupted
const_eval_invalid_align_details =
invalid align passed to `{$name}`: {$align} is {$err_kind ->
[not_power_of_two] not a power of 2
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use std::sync::atomic::Ordering::Relaxed;

use either::{Left, Right};

use rustc_data_structures::CTRL_C_RECEIVED;
use rustc_hir::def::DefKind;
use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
use rustc_middle::mir::{self, ConstAlloc, ConstValue};
Expand Down Expand Up @@ -79,7 +82,11 @@ fn eval_body_using_ecx<'mir, 'tcx>(
ecx.storage_live_for_always_live_locals()?;

// The main interpreter loop.
while ecx.step()? {}
while ecx.step()? {
if CTRL_C_RECEIVED.load(Relaxed) {
throw_exhaust!(Interrupted);
}
}

// Intern the result
intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,7 @@ impl ReportErrorExt for ResourceExhaustionInfo {
ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached,
ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted,
ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
ResourceExhaustionInfo::Interrupted => const_eval_interrupted,
}
}
fn add_args<G: EmissionGuarantee>(self, _: &mut Diag<'_, G>) {}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern crate tracing;
extern crate rustc_macros;

use std::fmt;
use std::sync::atomic::AtomicBool;

pub use rustc_index::static_assert_size;

Expand Down Expand Up @@ -161,3 +162,8 @@ macro_rules! external_bitflags_debug {
}
};
}

/// `rustc_driver::main` installs a handler that will set this to `true` if
/// the compiler has been sent a request to shut down, such as by a Ctrl-C.
/// This static is placed here so that it is available to all parts of the compiler.
pub static CTRL_C_RECEIVED: AtomicBool = AtomicBool::new(false);
1 change: 1 addition & 0 deletions compiler/rustc_driver_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
ctrlc = "3.4.4"
rustc_ast = { path = "../rustc_ast" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
use rustc_data_structures::profiling::{
get_resident_set_size, print_time_passes_entry, TimePassesFormat,
};
use rustc_data_structures::CTRL_C_RECEIVED;
use rustc_errors::emitter::stderr_destination;
use rustc_errors::registry::Registry;
use rustc_errors::{
Expand Down Expand Up @@ -1515,6 +1516,19 @@ pub fn main() -> ! {
signal_handler::install();
let mut callbacks = TimePassesCallbacks::default();
let using_internal_features = install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());

ctrlc::set_handler(move || {
// Indicate that we have been signaled to stop. If we were already signaled, exit
// immediately. In our interpreter loop we try to consult this value often, but if for
// whatever reason we don't get to that check or the cleanup we do upon finding that
// this bool has become true takes a long time, the exit here will promptly exit the
// process on the second Ctrl-C.
if CTRL_C_RECEIVED.swap(true, Ordering::Relaxed) {
std::process::exit(1);
}
})
.expect("Unable to install ctrlc handler");

let exit_code = catch_with_exit_code(|| {
RunCompiler::new(&args::raw_args(&early_dcx)?, &mut callbacks)
.set_using_internal_features(using_internal_features)
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,8 @@ pub enum ResourceExhaustionInfo {
MemoryExhausted,
/// The address space (of the target) is full.
AddressSpaceFull,
/// The compiler got an interrupt signal (a user ran out of patience).
Interrupted,
}

/// A trait for machine-specific errors (or other "machine stop" conditions).
Expand Down
14 changes: 8 additions & 6 deletions src/tools/miri/src/concurrency/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::num::TryFromIntError;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
use std::sync::atomic::Ordering::Relaxed;
use std::task::Poll;
use std::time::{Duration, SystemTime};

use either::Either;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::CTRL_C_RECEIVED;
use rustc_hir::def_id::DefId;
use rustc_index::{Idx, IndexVec};
use rustc_middle::mir::Mutability;
Expand Down Expand Up @@ -1045,21 +1046,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Run the core interpreter loop. Returns only when an interrupt occurs (an error or program
/// termination).
fn run_threads(&mut self) -> InterpResult<'tcx, !> {
static SIGNALED: AtomicBool = AtomicBool::new(false);
// In normal rustc, rustc_driver::main installs this handler. But we don't use that
// function, see src/bin/miri.rs.
ctrlc::set_handler(move || {
// Indicate that we have ben signaled to stop. If we were already signaled, exit
// Indicate that we have been signaled to stop. If we were already signaled, exit
// immediately. In our interpreter loop we try to consult this value often, but if for
// whatever reason we don't get to that check or the cleanup we do upon finding that
// this bool has become true takes a long time, the exit here will promptly exit the
// process on the second Ctrl-C.
if SIGNALED.swap(true, Relaxed) {
if CTRL_C_RECEIVED.swap(true, Relaxed) {
std::process::exit(1);
}
})
.unwrap();
.expect("Unable to install ctrlc handler");
let this = self.eval_context_mut();
loop {
if SIGNALED.load(Relaxed) {
if CTRL_C_RECEIVED.load(Relaxed) {
this.machine.handle_abnormal_termination();
std::process::exit(1);
}
Expand Down
3 changes: 3 additions & 0 deletions src/tools/tidy/src/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"byteorder", // via ruzstd in object in thorin-dwp
"cc",
"cfg-if",
"cfg_aliases",
"compiler_builtins",
"cpufeatures",
"crc32fast",
Expand All @@ -216,6 +217,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"crossbeam-epoch",
"crossbeam-utils",
"crypto-common",
"ctrlc",
"darling",
"darling_core",
"darling_macro",
Expand Down Expand Up @@ -281,6 +283,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
"memmap2",
"memoffset",
"miniz_oxide",
"nix",
"nu-ansi-term",
"num-conv",
"num_cpus",
Expand Down
4 changes: 3 additions & 1 deletion tests/run-make/jobserver-error/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ include ../tools.mk
# ignore-cross-compile

# Test compiler behavior in case environment specifies wrong jobserver.
# Note that by default, the compiler uses file descriptors 0 (stdin), 1 (stdout), 2 (stderr),
# but also 3 and 4 for either end of the ctrl-c signal handler self-pipe.

all:
bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=3,3" $(RUSTC)' 2>&1 | diff cannot_open_fd.stderr -
bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=5,5" $(RUSTC)' 2>&1 | diff cannot_open_fd.stderr -
bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=3,3" $(RUSTC) - 3</dev/null' 2>&1 | diff not_a_pipe.stderr -

# This test randomly fails, see https://github.com/rust-lang/rust/issues/110321
Expand Down
2 changes: 1 addition & 1 deletion tests/run-make/jobserver-error/cannot_open_fd.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=3,3"`: cannot open file descriptor 3 from the jobserver environment variable value: Bad file descriptor (os error 9)
warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=5,5"`: cannot open file descriptor 5 from the jobserver environment variable value: Bad file descriptor (os error 9)
|
= note: the build environment is likely misconfigured

Expand Down

0 comments on commit f7bf976

Please sign in to comment.