@@ -361,9 +361,12 @@ pub fn report_error<'tcx, 'mir>(
361361 } ;
362362
363363 let stacktrace = ecx. generate_stacktrace ( ) ;
364- let ( stacktrace, was_pruned ) = prune_stacktrace ( stacktrace, & ecx. machine ) ;
364+ let ( stacktrace, mut any_pruned ) = prune_stacktrace ( stacktrace, & ecx. machine ) ;
365365
366- // We want to dump the allocation if this is `InvalidUninitBytes`. Since `format_error` consumes `e`, we compute the outut early.
366+ let mut show_all_threads = false ;
367+
368+ // We want to dump the allocation if this is `InvalidUninitBytes`.
369+ // Since `format_interp_error` consumes `e`, we compute the outut early.
367370 let mut extra = String :: new ( ) ;
368371 match e. kind ( ) {
369372 UndefinedBehavior ( InvalidUninitBytes ( Some ( ( alloc_id, access) ) ) ) => {
@@ -375,6 +378,15 @@ pub fn report_error<'tcx, 'mir>(
375378 . unwrap ( ) ;
376379 writeln ! ( extra, "{:?}" , ecx. dump_alloc( * alloc_id) ) . unwrap ( ) ;
377380 }
381+ MachineStop ( info) => {
382+ let info = info. downcast_ref :: < TerminationInfo > ( ) . expect ( "invalid MachineStop payload" ) ;
383+ match info {
384+ TerminationInfo :: Deadlock => {
385+ show_all_threads = true ;
386+ }
387+ _ => { }
388+ }
389+ }
378390 _ => { }
379391 }
380392
@@ -387,18 +399,39 @@ pub fn report_error<'tcx, 'mir>(
387399 vec ! [ ] ,
388400 helps,
389401 & stacktrace,
402+ Some ( ecx. get_active_thread ( ) ) ,
390403 & ecx. machine ,
391404 ) ;
392405
406+ eprint ! ( "{extra}" ) ; // newlines are already in the string
407+
408+ if show_all_threads {
409+ for ( thread, stack) in ecx. machine . threads . all_stacks ( ) {
410+ if thread != ecx. get_active_thread ( ) {
411+ let stacktrace = Frame :: generate_stacktrace_from_stack ( stack) ;
412+ let ( stacktrace, was_pruned) = prune_stacktrace ( stacktrace, & ecx. machine ) ;
413+ any_pruned |= was_pruned;
414+ report_msg (
415+ DiagLevel :: Error ,
416+ format ! ( "deadlock: the evaluated program deadlocked" ) ,
417+ vec ! [ format!( "the evaluated program deadlocked" ) ] ,
418+ vec ! [ ] ,
419+ vec ! [ ] ,
420+ & stacktrace,
421+ Some ( thread) ,
422+ & ecx. machine ,
423+ )
424+ }
425+ }
426+ }
427+
393428 // Include a note like `std` does when we omit frames from a backtrace
394- if was_pruned {
429+ if any_pruned {
395430 ecx. tcx . dcx ( ) . note (
396431 "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace" ,
397432 ) ;
398433 }
399434
400- eprint ! ( "{extra}" ) ; // newlines are already in the string
401-
402435 // Debug-dump all locals.
403436 for ( i, frame) in ecx. active_thread_stack ( ) . iter ( ) . enumerate ( ) {
404437 trace ! ( "-------------------" ) ;
@@ -435,6 +468,7 @@ pub fn report_leaks<'mir, 'tcx>(
435468 vec ! [ ] ,
436469 vec ! [ ] ,
437470 & backtrace,
471+ None , // we don't know the thread this is from
438472 & ecx. machine ,
439473 ) ;
440474 }
@@ -457,6 +491,7 @@ pub fn report_msg<'tcx>(
457491 notes : Vec < ( Option < SpanData > , String ) > ,
458492 helps : Vec < ( Option < SpanData > , String ) > ,
459493 stacktrace : & [ FrameInfo < ' tcx > ] ,
494+ thread : Option < ThreadId > ,
460495 machine : & MiriMachine < ' _ , ' tcx > ,
461496) {
462497 let span = stacktrace. first ( ) . map_or ( DUMMY_SP , |fi| fi. span ) ;
@@ -506,12 +541,13 @@ pub fn report_msg<'tcx>(
506541 if extra_span {
507542 write ! ( backtrace_title, " (of the first span)" ) . unwrap ( ) ;
508543 }
509- let thread_name =
510- machine. threads . get_thread_display_name ( machine. threads . get_active_thread_id ( ) ) ;
511- if thread_name != "main" {
512- // Only print thread name if it is not `main`.
513- write ! ( backtrace_title, " on thread `{thread_name}`" ) . unwrap ( ) ;
514- } ;
544+ if let Some ( thread) = thread {
545+ let thread_name = machine. threads . get_thread_display_name ( thread) ;
546+ if thread_name != "main" {
547+ // Only print thread name if it is not `main`.
548+ write ! ( backtrace_title, " on thread `{thread_name}`" ) . unwrap ( ) ;
549+ } ;
550+ }
515551 write ! ( backtrace_title, ":" ) . unwrap ( ) ;
516552 err. note ( backtrace_title) ;
517553 for ( idx, frame_info) in stacktrace. iter ( ) . enumerate ( ) {
@@ -628,7 +664,16 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
628664 _ => vec ! [ ] ,
629665 } ;
630666
631- report_msg ( diag_level, title, vec ! [ msg] , notes, helps, & stacktrace, self ) ;
667+ report_msg (
668+ diag_level,
669+ title,
670+ vec ! [ msg] ,
671+ notes,
672+ helps,
673+ & stacktrace,
674+ Some ( self . threads . get_active_thread_id ( ) ) ,
675+ self ,
676+ ) ;
632677 }
633678}
634679
@@ -654,6 +699,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
654699 vec ! [ ] ,
655700 vec ! [ ] ,
656701 & stacktrace,
702+ Some ( this. get_active_thread ( ) ) ,
657703 & this. machine ,
658704 ) ;
659705 }
0 commit comments