@@ -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