@@ -29,7 +29,7 @@ use std::fmt;
2929use std:: fs;
3030use std:: io;
3131use std:: path:: { Path , PathBuf } ;
32- use std:: process:: { Output , Stdio } ;
32+ use std:: process:: { Output , Stdio , ExitStatus } ;
3333use std:: str;
3434use std:: env;
3535
@@ -510,21 +510,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
510510 sess. abort_if_errors ( ) ;
511511
512512 // Invoke the system linker
513- //
514- // Note that there's a terribly awful hack that really shouldn't be present
515- // in any compiler. Here an environment variable is supported to
516- // automatically retry the linker invocation if the linker looks like it
517- // segfaulted.
518- //
519- // Gee that seems odd, normally segfaults are things we want to know about!
520- // Unfortunately though in rust-lang/rust#38878 we're experiencing the
521- // linker segfaulting on Travis quite a bit which is causing quite a bit of
522- // pain to land PRs when they spuriously fail due to a segfault.
523- //
524- // The issue #38878 has some more debugging information on it as well, but
525- // this unfortunately looks like it's just a race condition in macOS's linker
526- // with some thread pool working in the background. It seems that no one
527- // currently knows a fix for this so in the meantime we're left with this...
528513 info ! ( "{:?}" , & cmd) ;
529514 let retry_on_segfault = env:: var ( "RUSTC_RETRY_LINKER_ON_SEGFAULT" ) . is_ok ( ) ;
530515 let mut prog;
@@ -567,21 +552,59 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
567552 info ! ( "{:?}" , & cmd) ;
568553 continue ;
569554 }
555+
556+ // Here's a terribly awful hack that really shouldn't be present in any
557+ // compiler. Here an environment variable is supported to automatically
558+ // retry the linker invocation if the linker looks like it segfaulted.
559+ //
560+ // Gee that seems odd, normally segfaults are things we want to know
561+ // about! Unfortunately though in rust-lang/rust#38878 we're
562+ // experiencing the linker segfaulting on Travis quite a bit which is
563+ // causing quite a bit of pain to land PRs when they spuriously fail
564+ // due to a segfault.
565+ //
566+ // The issue #38878 has some more debugging information on it as well,
567+ // but this unfortunately looks like it's just a race condition in
568+ // macOS's linker with some thread pool working in the background. It
569+ // seems that no one currently knows a fix for this so in the meantime
570+ // we're left with this...
570571 if !retry_on_segfault || i > 3 {
571572 break
572573 }
573574 let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11" ;
574575 let msg_bus = "clang: error: unable to execute command: Bus error: 10" ;
575- if !( out. contains ( msg_segv) || out. contains ( msg_bus) ) {
576- break
576+ if out. contains ( msg_segv) || out. contains ( msg_bus) {
577+ warn ! (
578+ "looks like the linker segfaulted when we tried to call it, \
579+ automatically retrying again. cmd = {:?}, out = {}.",
580+ cmd,
581+ out,
582+ ) ;
583+ continue ;
577584 }
578585
579- warn ! (
580- "looks like the linker segfaulted when we tried to call it, \
581- automatically retrying again. cmd = {:?}, out = {}.",
582- cmd,
583- out,
584- ) ;
586+ if is_illegal_instruction ( & output. status ) {
587+ warn ! (
588+ "looks like the linker hit an illegal instruction when we \
589+ tried to call it, automatically retrying again. cmd = {:?}, ]\
590+ out = {}, status = {}.",
591+ cmd,
592+ out,
593+ output. status,
594+ ) ;
595+ continue ;
596+ }
597+
598+ #[ cfg( unix) ]
599+ fn is_illegal_instruction ( status : & ExitStatus ) -> bool {
600+ use std:: os:: unix:: prelude:: * ;
601+ status. signal ( ) == Some ( libc:: SIGILL )
602+ }
603+
604+ #[ cfg( windows) ]
605+ fn is_illegal_instruction ( _status : & ExitStatus ) -> bool {
606+ false
607+ }
585608 }
586609
587610 match prog {
0 commit comments