Skip to content

Commit 239828e

Browse files
authored
Rollup merge of rust-lang#62171 - alexcrichton:more-restarts, r=eddyb
rustc: Retry SIGILL linker invocations We've seen quite a few issues with spurious illegal instructions getting executed on OSX on CI recently. For whatever reason `cc` itself is executing an illegal instruction and we're not really getting any other information about what's happening. Since we're already retrying the linker when it segfaults, let's just continue to retry everything and automatically reinvoke the linker when it fails with an illegal instruction.
2 parents 8e5268b + b608749 commit 239828e

File tree

1 file changed

+47
-24
lines changed
  • src/librustc_codegen_ssa/back

1 file changed

+47
-24
lines changed

src/librustc_codegen_ssa/back/link.rs

+47-24
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use std::fmt;
2929
use std::fs;
3030
use std::io;
3131
use std::path::{Path, PathBuf};
32-
use std::process::{Output, Stdio};
32+
use std::process::{Output, Stdio, ExitStatus};
3333
use std::str;
3434
use 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

Comments
 (0)