Abort in deadlock handler if we fail to get a query map
This commit is contained in:
parent
01dc45c10e
commit
077b8d5c37
5 changed files with 25 additions and 12 deletions
|
@ -192,7 +192,16 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
|
|||
// `TyCtxt` TLS reference here.
|
||||
let query_map = current_gcx2.access(|gcx| {
|
||||
tls::enter_context(&tls::ImplicitCtxt::new(gcx), || {
|
||||
tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs())
|
||||
tls::with(|tcx| {
|
||||
let (query_map, complete) = QueryCtxt::new(tcx).collect_active_jobs();
|
||||
if !complete {
|
||||
eprintln!("internal compiler error: failed to get query map in deadlock handler, aborting process");
|
||||
// We need to abort here as we failed to resolve the deadlock,
|
||||
// otherwise the compiler could just hang,
|
||||
process::abort();
|
||||
}
|
||||
query_map
|
||||
})
|
||||
})
|
||||
});
|
||||
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,
|
|||
.name("rustc query cycle handler".to_string())
|
||||
.spawn(move || {
|
||||
let on_panic = defer(|| {
|
||||
eprintln!("query cycle handler thread panicked, aborting process");
|
||||
eprintln!("internal compiler error: query cycle handler thread panicked, aborting process");
|
||||
// We need to abort here as we failed to resolve the deadlock,
|
||||
// otherwise the compiler could just hang,
|
||||
process::abort();
|
||||
|
|
|
@ -79,14 +79,15 @@ impl QueryContext for QueryCtxt<'_> {
|
|||
tls::with_related_context(self.tcx, |icx| icx.query)
|
||||
}
|
||||
|
||||
fn collect_active_jobs(self) -> QueryMap {
|
||||
fn collect_active_jobs(self) -> (QueryMap, bool) {
|
||||
let mut jobs = QueryMap::default();
|
||||
let mut complete = true;
|
||||
|
||||
for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
|
||||
collect(self.tcx, &mut jobs);
|
||||
collect(self.tcx, &mut jobs, &mut complete);
|
||||
}
|
||||
|
||||
jobs
|
||||
(jobs, complete)
|
||||
}
|
||||
|
||||
// Interactions with on_disk_cache
|
||||
|
@ -139,7 +140,8 @@ impl QueryContext for QueryCtxt<'_> {
|
|||
}
|
||||
|
||||
fn depth_limit_error(self, job: QueryJobId) {
|
||||
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
|
||||
// FIXME: `collect_active_jobs` expects no locks to be held, which doesn't hold for this call.
|
||||
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs().0);
|
||||
|
||||
let suggested_limit = match self.recursion_limit() {
|
||||
Limit(0) => Limit(2),
|
||||
|
@ -677,7 +679,7 @@ macro_rules! define_queries {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap) {
|
||||
pub(crate) fn try_collect_active_jobs<'tcx>(tcx: TyCtxt<'tcx>, qmap: &mut QueryMap, complete: &mut bool) {
|
||||
let make_query = |tcx, key| {
|
||||
let kind = rustc_middle::dep_graph::dep_kinds::$name;
|
||||
let name = stringify!($name);
|
||||
|
@ -692,6 +694,7 @@ macro_rules! define_queries {
|
|||
// don't `unwrap()` here, just manually check for `None` and do best-effort error
|
||||
// reporting.
|
||||
if res.is_none() {
|
||||
*complete = false;
|
||||
tracing::warn!(
|
||||
"Failed to collect active jobs for query with name `{}`!",
|
||||
stringify!($name)
|
||||
|
@ -756,7 +759,7 @@ macro_rules! define_queries {
|
|||
|
||||
// These arrays are used for iteration and can't be indexed by `DepKind`.
|
||||
|
||||
const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] =
|
||||
const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap, &mut bool)] =
|
||||
&[$(query_impl::$name::try_collect_active_jobs),*];
|
||||
|
||||
const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[
|
||||
|
|
|
@ -588,7 +588,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
|
|||
// state if it was responsible for triggering the panic.
|
||||
let mut count_printed = 0;
|
||||
let mut count_total = 0;
|
||||
let query_map = qcx.collect_active_jobs();
|
||||
let query_map = qcx.collect_active_jobs().0;
|
||||
|
||||
if let Some(ref mut file) = file {
|
||||
let _ = writeln!(file, "\n\nquery stack during panic:");
|
||||
|
|
|
@ -86,7 +86,7 @@ pub trait QueryContext: HasDepContext {
|
|||
/// Get the query information from the TLS context.
|
||||
fn current_query_job(self) -> Option<QueryJobId>;
|
||||
|
||||
fn collect_active_jobs(self) -> QueryMap;
|
||||
fn collect_active_jobs(self) -> (QueryMap, bool);
|
||||
|
||||
/// Load a side effect associated to the node in the previous session.
|
||||
fn load_side_effect(
|
||||
|
|
|
@ -250,8 +250,9 @@ where
|
|||
Q: QueryConfig<Qcx>,
|
||||
Qcx: QueryContext,
|
||||
{
|
||||
let error =
|
||||
try_execute.find_cycle_in_stack(qcx.collect_active_jobs(), &qcx.current_query_job(), span);
|
||||
let (query_map, complete) = qcx.collect_active_jobs();
|
||||
assert!(complete, "failed to collect active queries");
|
||||
let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span);
|
||||
(mk_cycle(query, qcx, error), None)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue