@@ -361,9 +361,12 @@ pub fn report_error<'tcx, 'mir>(
361
361
} ;
362
362
363
363
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 ) ;
365
365
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.
367
370
let mut extra = String :: new ( ) ;
368
371
match e. kind ( ) {
369
372
UndefinedBehavior ( InvalidUninitBytes ( Some ( ( alloc_id, access) ) ) ) => {
@@ -375,6 +378,15 @@ pub fn report_error<'tcx, 'mir>(
375
378
. unwrap ( ) ;
376
379
writeln ! ( extra, "{:?}" , ecx. dump_alloc( * alloc_id) ) . unwrap ( ) ;
377
380
}
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
+ }
378
390
_ => { }
379
391
}
380
392
@@ -387,18 +399,39 @@ pub fn report_error<'tcx, 'mir>(
387
399
vec ! [ ] ,
388
400
helps,
389
401
& stacktrace,
402
+ Some ( ecx. get_active_thread ( ) ) ,
390
403
& ecx. machine ,
391
404
) ;
392
405
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
+
393
428
// Include a note like `std` does when we omit frames from a backtrace
394
- if was_pruned {
429
+ if any_pruned {
395
430
ecx. tcx . dcx ( ) . note (
396
431
"some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace" ,
397
432
) ;
398
433
}
399
434
400
- eprint ! ( "{extra}" ) ; // newlines are already in the string
401
-
402
435
// Debug-dump all locals.
403
436
for ( i, frame) in ecx. active_thread_stack ( ) . iter ( ) . enumerate ( ) {
404
437
trace ! ( "-------------------" ) ;
@@ -435,6 +468,7 @@ pub fn report_leaks<'mir, 'tcx>(
435
468
vec ! [ ] ,
436
469
vec ! [ ] ,
437
470
& backtrace,
471
+ None , // we don't know the thread this is from
438
472
& ecx. machine ,
439
473
) ;
440
474
}
@@ -445,6 +479,24 @@ pub fn report_leaks<'mir, 'tcx>(
445
479
}
446
480
}
447
481
482
+ fn emit_stacktrace < ' tcx > (
483
+ stacktrace : & [ FrameInfo < ' tcx > ] ,
484
+ machine : & MiriMachine < ' _ , ' tcx > ,
485
+ err : & mut Diag < ' _ , ( ) > ,
486
+ ) {
487
+ for ( idx, frame_info) in stacktrace. iter ( ) . enumerate ( ) {
488
+ let is_local = machine. is_local ( frame_info) ;
489
+ // No span for non-local frames and the first frame (which is the error site).
490
+ if is_local && idx > 0 {
491
+ err. subdiagnostic ( err. dcx , frame_info. as_note ( machine. tcx ) ) ;
492
+ } else {
493
+ let sm = machine. tcx . sess . source_map ( ) ;
494
+ let span = sm. span_to_embeddable_string ( frame_info. span ) ;
495
+ err. note ( format ! ( "{frame_info} at {span}" ) ) ;
496
+ }
497
+ }
498
+ }
499
+
448
500
/// Report an error or note (depending on the `error` argument) with the given stacktrace.
449
501
/// Also emits a full stacktrace of the interpreter stack.
450
502
/// We want to present a multi-line span message for some errors. Diagnostics do not support this
@@ -457,6 +509,7 @@ pub fn report_msg<'tcx>(
457
509
notes : Vec < ( Option < SpanData > , String ) > ,
458
510
helps : Vec < ( Option < SpanData > , String ) > ,
459
511
stacktrace : & [ FrameInfo < ' tcx > ] ,
512
+ thread : Option < ThreadId > ,
460
513
machine : & MiriMachine < ' _ , ' tcx > ,
461
514
) {
462
515
let span = stacktrace. first ( ) . map_or ( DUMMY_SP , |fi| fi. span ) ;
@@ -502,29 +555,22 @@ pub fn report_msg<'tcx>(
502
555
}
503
556
504
557
// Add backtrace
558
+ // Compute backtrace title.
505
559
let mut backtrace_title = String :: from ( "BACKTRACE" ) ;
506
560
if extra_span {
507
561
write ! ( backtrace_title, " (of the first span)" ) . unwrap ( ) ;
508
562
}
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
- } ;
563
+ if let Some ( thread) = thread {
564
+ let thread_name = machine. threads . get_thread_display_name ( thread) ;
565
+ if thread_name != "main" {
566
+ // Only print thread name if it is not `main`.
567
+ write ! ( backtrace_title, " on thread `{thread_name}`" ) . unwrap ( ) ;
568
+ } ;
569
+ }
515
570
write ! ( backtrace_title, ":" ) . unwrap ( ) ;
516
571
err. note ( backtrace_title) ;
517
- for ( idx, frame_info) in stacktrace. iter ( ) . enumerate ( ) {
518
- let is_local = machine. is_local ( frame_info) ;
519
- // No span for non-local frames and the first frame (which is the error site).
520
- if is_local && idx > 0 {
521
- err. subdiagnostic ( err. dcx , frame_info. as_note ( machine. tcx ) ) ;
522
- } else {
523
- let sm = sess. source_map ( ) ;
524
- let span = sm. span_to_embeddable_string ( frame_info. span ) ;
525
- err. note ( format ! ( "{frame_info} at {span}" ) ) ;
526
- }
527
- }
572
+ // Add backtrace itself.
573
+ emit_stacktrace ( stacktrace, machine, & mut err) ;
528
574
529
575
err. emit ( ) ;
530
576
}
@@ -628,7 +674,16 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
628
674
_ => vec ! [ ] ,
629
675
} ;
630
676
631
- report_msg ( diag_level, title, vec ! [ msg] , notes, helps, & stacktrace, self ) ;
677
+ report_msg (
678
+ diag_level,
679
+ title,
680
+ vec ! [ msg] ,
681
+ notes,
682
+ helps,
683
+ & stacktrace,
684
+ Some ( self . threads . get_active_thread_id ( ) ) ,
685
+ self ,
686
+ ) ;
632
687
}
633
688
}
634
689
@@ -654,6 +709,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
654
709
vec ! [ ] ,
655
710
vec ! [ ] ,
656
711
& stacktrace,
712
+ Some ( this. get_active_thread ( ) ) ,
657
713
& this. machine ,
658
714
) ;
659
715
}
0 commit comments