Skip to content

Commit b82d940

Browse files
committed
avoid deadlock when reporting ice
1 parent c86e7fb commit b82d940

File tree

1 file changed

+29
-1
lines changed
  • compiler/rustc_query_system/src/query

1 file changed

+29
-1
lines changed

compiler/rustc_query_system/src/query/job.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ pub(crate) fn report_cycle<'a, D: DepKind>(
612612
cycle_diag.into_diagnostic(&sess.parse_sess.span_diagnostic)
613613
}
614614

615-
pub fn print_query_stack<Qcx: QueryContext>(
615+
pub fn print_query_stack<Qcx: QueryContext + rustc_data_structures::sync::Send>(
616616
qcx: Qcx,
617617
mut current_query: Option<QueryJobId>,
618618
handler: &Handler,
@@ -622,8 +622,36 @@ pub fn print_query_stack<Qcx: QueryContext>(
622622
// a panic hook, which means that the global `Handler` may be in a weird
623623
// state if it was responsible for triggering the panic.
624624
let mut i = 0;
625+
626+
#[cfg(not(parallel_compiler))]
625627
let query_map = qcx.try_collect_active_jobs();
626628

629+
// `try_collect_active_jobs` may deadlock when reporting ICE.
630+
// So we add a timeout detector to escape the deadlock in time.
631+
#[cfg(parallel_compiler)]
632+
let query_map = {
633+
use std::sync::mpsc::channel;
634+
use std::time::Duration;
635+
636+
let timeout = Duration::from_secs(5); // Set the timeout to 5 seconds
637+
638+
let (tx, rx) = channel();
639+
let (query_map, _) = rayon_core::join(
640+
move || {
641+
// Panic here since the second work may stuck into deadlocks
642+
match rx.recv_timeout(timeout) {
643+
Ok(result) => result,
644+
Err(_) => panic!("print query stack failed: time out"),
645+
}
646+
},
647+
move || {
648+
let query_map = qcx.try_collect_active_jobs();
649+
tx.send(query_map).unwrap();
650+
},
651+
);
652+
query_map
653+
};
654+
627655
while let Some(query) = current_query {
628656
if Some(i) == num_frames {
629657
break;

0 commit comments

Comments
 (0)