@@ -612,7 +612,7 @@ pub(crate) fn report_cycle<'a, D: DepKind>(
612
612
cycle_diag. into_diagnostic ( & sess. parse_sess . span_diagnostic )
613
613
}
614
614
615
- pub fn print_query_stack < Qcx : QueryContext > (
615
+ pub fn print_query_stack < Qcx : QueryContext + rustc_data_structures :: sync :: Send > (
616
616
qcx : Qcx ,
617
617
mut current_query : Option < QueryJobId > ,
618
618
handler : & Handler ,
@@ -622,8 +622,36 @@ pub fn print_query_stack<Qcx: QueryContext>(
622
622
// a panic hook, which means that the global `Handler` may be in a weird
623
623
// state if it was responsible for triggering the panic.
624
624
let mut i = 0 ;
625
+
626
+ #[ cfg( not( parallel_compiler) ) ]
625
627
let query_map = qcx. try_collect_active_jobs ( ) ;
626
628
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
+
627
655
while let Some ( query) = current_query {
628
656
if Some ( i) == num_frames {
629
657
break ;
0 commit comments