Skip to content

Commit 79faa4b

Browse files
committed
Abort in deadlock handler if we fail to get a query map
1 parent 227690a commit 79faa4b

File tree

5 files changed

+25
-12
lines changed

5 files changed

+25
-12
lines changed

compiler/rustc_interface/src/util.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,16 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
192192
// `TyCtxt` TLS reference here.
193193
let query_map = current_gcx2.access(|gcx| {
194194
tls::enter_context(&tls::ImplicitCtxt::new(gcx), || {
195-
tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs())
195+
tls::with(|tcx| {
196+
let (query_map, complete) = QueryCtxt::new(tcx).collect_active_jobs();
197+
if !complete {
198+
eprintln!("internal compiler error: failed to get query map in deadlock handler, aborting process");
199+
// We need to abort here as we failed to resolve the deadlock,
200+
// otherwise the compiler could just hang,
201+
process::abort();
202+
}
203+
query_map
204+
})
196205
})
197206
});
198207
let query_map = FromDyn::from(query_map);
@@ -201,7 +210,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
201210
.name("rustc query cycle handler".to_string())
202211
.spawn(move || {
203212
let on_panic = defer(|| {
204-
eprintln!("query cycle handler thread panicked, aborting process");
213+
eprintln!("internal compiler error: query cycle handler thread panicked, aborting process");
205214
// We need to abort here as we failed to resolve the deadlock,
206215
// otherwise the compiler could just hang,
207216
process::abort();

compiler/rustc_query_impl/src/plumbing.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,15 @@ impl QueryContext for QueryCtxt<'_> {
8282
tls::with_related_context(self.tcx, |icx| icx.query)
8383
}
8484

85-
fn collect_active_jobs(self) -> QueryMap {
85+
fn collect_active_jobs(self) -> (QueryMap, bool) {
8686
let mut jobs = QueryMap::default();
87+
let mut complete = true;
8788

8889
for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
89-
collect(self.tcx, &mut jobs);
90+
collect(self.tcx, &mut jobs, &mut complete);
9091
}
9192

92-
jobs
93+
(jobs, complete)
9394
}
9495

9596
// Interactions with on_disk_cache
@@ -155,7 +156,8 @@ impl QueryContext for QueryCtxt<'_> {
155156
}
156157

157158
fn depth_limit_error(self, job: QueryJobId) {
158-
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
159+
// FIXME: `collect_active_jobs` expects no locks to be held, which doesn't hold for this call.
160+
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs().0);
159161

160162
let suggested_limit = match self.recursion_limit() {
161163
Limit(0) => Limit(2),
@@ -693,7 +695,7 @@ macro_rules! define_queries {
693695
}
694696
}
695697

696-
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
698+
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap, complete: &mut bool) {
697699
let make_query = |tcx, key| {
698700
let kind = rustc_middle::dep_graph::dep_kinds::$name;
699701
let name = stringify!($name);
@@ -708,6 +710,7 @@ macro_rules! define_queries {
708710
// don't `unwrap()` here, just manually check for `None` and do best-effort error
709711
// reporting.
710712
if res.is_none() {
713+
*complete = false;
711714
tracing::warn!(
712715
"Failed to collect active jobs for query with name `{}`!",
713716
stringify!($name)
@@ -772,7 +775,7 @@ macro_rules! define_queries {
772775

773776
// These arrays are used for iteration and can't be indexed by `DepKind`.
774777

775-
const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] =
778+
const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap, &mut bool)] =
776779
&[$(query_impl::$name::try_collect_active_jobs),*];
777780

778781
const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[

compiler/rustc_query_system/src/query/job.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
588588
// state if it was responsible for triggering the panic.
589589
let mut count_printed = 0;
590590
let mut count_total = 0;
591-
let query_map = qcx.collect_active_jobs();
591+
let query_map = qcx.collect_active_jobs().0;
592592

593593
if let Some(ref mut file) = file {
594594
let _ = writeln!(file, "\n\nquery stack during panic:");

compiler/rustc_query_system/src/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub trait QueryContext: HasDepContext {
9999
/// Get the query information from the TLS context.
100100
fn current_query_job(self) -> Option<QueryJobId>;
101101

102-
fn collect_active_jobs(self) -> QueryMap;
102+
fn collect_active_jobs(self) -> (QueryMap, bool);
103103

104104
/// Load side effects associated to the node in the previous session.
105105
fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects;

compiler/rustc_query_system/src/query/plumbing.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,9 @@ where
254254
Q: QueryConfig<Qcx>,
255255
Qcx: QueryContext,
256256
{
257-
let error =
258-
try_execute.find_cycle_in_stack(qcx.collect_active_jobs(), &qcx.current_query_job(), span);
257+
let (query_map, complete) = qcx.collect_active_jobs();
258+
assert!(complete, "failed to collect active queries");
259+
let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span);
259260
(mk_cycle(query, qcx, error), None)
260261
}
261262

0 commit comments

Comments
 (0)