@@ -574,7 +574,21 @@ fn process_stat_output(
574574 return Err ( DeserializeStatError :: NoOutput ( output) ) ;
575575 }
576576 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+ }
578592 _ => ( None , None ) ,
579593 } ;
580594 Ok ( ( stats, profile, files) )
@@ -636,12 +650,27 @@ fn parse_self_profile(
636650 let ( profile, files) = if let Some ( profile_path) = full_path {
637651 // measureme 0.8+ uses a single file
638652 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+
645674 let profile = SelfProfile {
646675 artifact_sizes : results. artifact_sizes ,
647676 } ;
0 commit comments