@@ -574,7 +574,21 @@ fn process_stat_output(
574
574
return Err ( DeserializeStatError :: NoOutput ( output) ) ;
575
575
}
576
576
let ( profile, files) = match ( self_profile_dir, self_profile_crate) {
577
- ( Some ( dir) , Some ( krate) ) => parse_self_profile ( dir, krate) ?,
577
+ ( Some ( dir) , Some ( krate) ) => {
578
+ // FIXME: errors reading the self-profile data should be recorded as benchmark failures
579
+ // and made more visible in the UI. Until then, we only log errors and continue with the
580
+ // run, as if we had no self-profile data.
581
+ // The self-profile page already supports missing data, but it's unclear exactly how the
582
+ // rest of the site handles this situation.
583
+ // In any case it's better than crashing the collector and looping indefinitely trying
584
+ // to to complete a run -- which happens if we propagate `parse_self_profile`'s errors
585
+ // up to the caller.
586
+ if let Ok ( self_profile_data) = parse_self_profile ( dir, krate) {
587
+ self_profile_data
588
+ } else {
589
+ ( None , None )
590
+ }
591
+ }
578
592
_ => ( None , None ) ,
579
593
} ;
580
594
Ok ( ( stats, profile, files) )
@@ -636,12 +650,27 @@ fn parse_self_profile(
636
650
let ( profile, files) = if let Some ( profile_path) = full_path {
637
651
// measureme 0.8+ uses a single file
638
652
let data = fs:: read ( & profile_path) ?;
639
- let results = analyzeme:: ProfilingData :: from_paged_buffer ( data, None )
640
- . map_err ( |error| {
641
- eprintln ! ( "Cannot read self-profile data: {error:?}" ) ;
642
- std:: io:: Error :: new ( ErrorKind :: InvalidData , error)
643
- } ) ?
644
- . perform_analysis ( ) ;
653
+
654
+ // HACK: `decodeme` can unexpectedly panic on invalid data produced by rustc. We catch this
655
+ // here until it's fixed and emits a proper error.
656
+ let res =
657
+ std:: panic:: catch_unwind ( || analyzeme:: ProfilingData :: from_paged_buffer ( data, None ) ) ;
658
+ let results = match res {
659
+ Ok ( Ok ( profiling_data) ) => profiling_data. perform_analysis ( ) ,
660
+ Ok ( Err ( error) ) => {
661
+ // A "regular" error in measureme.
662
+ log:: error!( "Cannot read self-profile data: {error:?}" ) ;
663
+ return Err ( std:: io:: Error :: new ( ErrorKind :: InvalidData , error) ) ;
664
+ }
665
+ Err ( error) => {
666
+ // An unexpected panic in measureme: it sometimes happens when encountering some
667
+ // cases of invalid mm_profdata files.
668
+ let error = format ! ( "Unexpected measureme error with self-profile data: {error:?}" ) ;
669
+ log:: error!( "{error}" ) ;
670
+ return Err ( std:: io:: Error :: new ( ErrorKind :: InvalidData , error) ) ;
671
+ }
672
+ } ;
673
+
645
674
let profile = SelfProfile {
646
675
artifact_sizes : results. artifact_sizes ,
647
676
} ;
0 commit comments