@@ -752,8 +752,54 @@ fn link_natively(sess: &Session,
752
752
sess. abort_if_errors ( ) ;
753
753
754
754
// Invoke the system linker
755
+ //
756
+ // Note that there's a terribly awful hack that really shouldn't be present
757
+ // in any compiler. Here an environment variable is supported to
758
+ // automatically retry the linker invocation if the linker looks like it
759
+ // segfaulted.
760
+ //
761
+ // Gee that seems odd, normally segfaults are things we want to know about!
762
+ // Unfortunately though in rust-lang/rust#38878 we're experiencing the
763
+ // linker segfaulting on Travis quite a bit which is causing quite a bit of
764
+ // pain to land PRs when they spuriously fail due to a segfault.
765
+ //
766
+ // The issue #38878 has some more debugging information on it as well, but
767
+ // this unfortunately looks like it's just a race condition in OSX's linker
768
+ // with some thread pool working in the background. It seems that no one
769
+ // currently knows a fix for this so in the meantime we're left with this...
755
770
info ! ( "{:?}" , & cmd) ;
756
- let prog = time ( sess. time_passes ( ) , "running linker" , || cmd. output ( ) ) ;
771
+ let retry_on_segfault = env:: var ( "RUSTC_RETRY_LINKER_ON_SEGFAULT" ) . is_ok ( ) ;
772
+ let mut prog;
773
+ let mut i = 0 ;
774
+ loop {
775
+ i += 1 ;
776
+ prog = time ( sess. time_passes ( ) , "running linker" , || cmd. output ( ) ) ;
777
+ if !retry_on_segfault || i > 3 {
778
+ break
779
+ }
780
+ let output = match prog {
781
+ Ok ( ref output) => output,
782
+ Err ( _) => break ,
783
+ } ;
784
+ if output. status . success ( ) {
785
+ break
786
+ }
787
+ let mut out = output. stderr . clone ( ) ;
788
+ out. extend ( & output. stdout ) ;
789
+ let out = String :: from_utf8_lossy ( & out) ;
790
+ let msg = "clang: error: unable to execute command: \
791
+ Segmentation fault: 11";
792
+ if !out. contains ( msg) {
793
+ break
794
+ }
795
+
796
+ sess. struct_warn ( "looks like the linker segfaulted when we tried to \
797
+ call it, automatically retrying again")
798
+ . note ( & format ! ( "{:?}" , cmd) )
799
+ . note ( & out)
800
+ . emit ( ) ;
801
+ }
802
+
757
803
match prog {
758
804
Ok ( prog) => {
759
805
fn escape_string ( s : & [ u8 ] ) -> String {
0 commit comments