@@ -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