Auto merge of #40422 - alexcrichton:retry-linker-segfault, r=arielb1
rustc: Support auto-retry linking on a segfault This is a last-ditch attempt to help our pain with dealing with #38878 on the bots. A new environment variable is added to the compiler, `RUSTC_RETRY_LINKER_ON_SEGFAULT`, which will instruct the compiler to automatically retry the final linker invocation if it looks like the linker segfaulted (up to 2 extra times). Unfortunately there have been no successful attempts to debug #38878. The only information seems to be that the linker (e.g. `ld` on OSX) is segfaulting somewhere in some thread pool implementation. This appears to be spurious as failed PRs will later merge. The hope is that this helps the queue keep moving without clogging and delaying PRs due to #38878.
This commit is contained in:
commit
71c058b305
|
@ -44,6 +44,7 @@ matrix:
|
||||||
RUST_CHECK_TARGET=check
|
RUST_CHECK_TARGET=check
|
||||||
RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin
|
RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin
|
||||||
SRC=.
|
SRC=.
|
||||||
|
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode8.2
|
osx_image: xcode8.2
|
||||||
install: &osx_install_sccache >
|
install: &osx_install_sccache >
|
||||||
|
@ -53,6 +54,7 @@ matrix:
|
||||||
RUST_CHECK_TARGET=check
|
RUST_CHECK_TARGET=check
|
||||||
RUST_CONFIGURE_ARGS=--build=i686-apple-darwin
|
RUST_CONFIGURE_ARGS=--build=i686-apple-darwin
|
||||||
SRC=.
|
SRC=.
|
||||||
|
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode8.2
|
osx_image: xcode8.2
|
||||||
install: *osx_install_sccache
|
install: *osx_install_sccache
|
||||||
|
@ -62,6 +64,7 @@ matrix:
|
||||||
RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended"
|
RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended"
|
||||||
SRC=.
|
SRC=.
|
||||||
DEPLOY=1
|
DEPLOY=1
|
||||||
|
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode8.2
|
osx_image: xcode8.2
|
||||||
install: >
|
install: >
|
||||||
|
@ -74,6 +77,7 @@ matrix:
|
||||||
RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended"
|
RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended"
|
||||||
SRC=.
|
SRC=.
|
||||||
DEPLOY=1
|
DEPLOY=1
|
||||||
|
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode8.2
|
osx_image: xcode8.2
|
||||||
install: *osx_install_sccache
|
install: *osx_install_sccache
|
||||||
|
@ -88,6 +92,7 @@ matrix:
|
||||||
RUST_CONFIGURE_ARGS="--enable-extended"
|
RUST_CONFIGURE_ARGS="--enable-extended"
|
||||||
SRC=.
|
SRC=.
|
||||||
DEPLOY_ALT=1
|
DEPLOY_ALT=1
|
||||||
|
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
|
||||||
os: osx
|
os: osx
|
||||||
osx_image: xcode8.2
|
osx_image: xcode8.2
|
||||||
install: *osx_install_sccache
|
install: *osx_install_sccache
|
||||||
|
|
|
@ -752,8 +752,54 @@ fn link_natively(sess: &Session,
|
||||||
sess.abort_if_errors();
|
sess.abort_if_errors();
|
||||||
|
|
||||||
// Invoke the system linker
|
// Invoke the system linker
|
||||||
|
//
|
||||||
|
// Note that there's a terribly awful hack that really shouldn't be present
|
||||||
|
// in any compiler. Here an environment variable is supported to
|
||||||
|
// automatically retry the linker invocation if the linker looks like it
|
||||||
|
// segfaulted.
|
||||||
|
//
|
||||||
|
// Gee that seems odd, normally segfaults are things we want to know about!
|
||||||
|
// Unfortunately though in rust-lang/rust#38878 we're experiencing the
|
||||||
|
// linker segfaulting on Travis quite a bit which is causing quite a bit of
|
||||||
|
// pain to land PRs when they spuriously fail due to a segfault.
|
||||||
|
//
|
||||||
|
// The issue #38878 has some more debugging information on it as well, but
|
||||||
|
// this unfortunately looks like it's just a race condition in OSX's linker
|
||||||
|
// with some thread pool working in the background. It seems that no one
|
||||||
|
// currently knows a fix for this so in the meantime we're left with this...
|
||||||
info!("{:?}", &cmd);
|
info!("{:?}", &cmd);
|
||||||
let prog = time(sess.time_passes(), "running linker", || cmd.output());
|
let retry_on_segfault = env::var("RUSTC_RETRY_LINKER_ON_SEGFAULT").is_ok();
|
||||||
|
let mut prog;
|
||||||
|
let mut i = 0;
|
||||||
|
loop {
|
||||||
|
i += 1;
|
||||||
|
prog = time(sess.time_passes(), "running linker", || cmd.output());
|
||||||
|
if !retry_on_segfault || i > 3 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let output = match prog {
|
||||||
|
Ok(ref output) => output,
|
||||||
|
Err(_) => break,
|
||||||
|
};
|
||||||
|
if output.status.success() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let mut out = output.stderr.clone();
|
||||||
|
out.extend(&output.stdout);
|
||||||
|
let out = String::from_utf8_lossy(&out);
|
||||||
|
let msg = "clang: error: unable to execute command: \
|
||||||
|
Segmentation fault: 11";
|
||||||
|
if !out.contains(msg) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
sess.struct_warn("looks like the linker segfaulted when we tried to \
|
||||||
|
call it, automatically retrying again")
|
||||||
|
.note(&format!("{:?}", cmd))
|
||||||
|
.note(&out)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
|
||||||
match prog {
|
match prog {
|
||||||
Ok(prog) => {
|
Ok(prog) => {
|
||||||
fn escape_string(s: &[u8]) -> String {
|
fn escape_string(s: &[u8]) -> String {
|
||||||
|
|
Loading…
Reference in New Issue