Skip to content

Commit 65c8424

Browse files
committed
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.
2 parents f573db4 + 993eae1 commit 65c8424

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

.travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ matrix:
4444
RUST_CHECK_TARGET=check
4545
RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin
4646
SRC=.
47+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
4748
os: osx
4849
osx_image: xcode8.2
4950
install: &osx_install_sccache >
@@ -53,6 +54,7 @@ matrix:
5354
RUST_CHECK_TARGET=check
5455
RUST_CONFIGURE_ARGS=--build=i686-apple-darwin
5556
SRC=.
57+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
5658
os: osx
5759
osx_image: xcode8.2
5860
install: *osx_install_sccache
@@ -62,6 +64,7 @@ matrix:
6264
RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended"
6365
SRC=.
6466
DEPLOY=1
67+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
6568
os: osx
6669
osx_image: xcode8.2
6770
install: >
@@ -74,6 +77,7 @@ matrix:
7477
RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended"
7578
SRC=.
7679
DEPLOY=1
80+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
7781
os: osx
7882
osx_image: xcode8.2
7983
install: *osx_install_sccache
@@ -88,6 +92,7 @@ matrix:
8892
RUST_CONFIGURE_ARGS="--enable-extended"
8993
SRC=.
9094
DEPLOY_ALT=1
95+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
9196
os: osx
9297
osx_image: xcode8.2
9398
install: *osx_install_sccache

src/librustc_trans/back/link.rs

+47-1
Original file line numberDiff line numberDiff line change
@@ -752,8 +752,54 @@ fn link_natively(sess: &Session,
752752
sess.abort_if_errors();
753753

754754
// 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...
755770
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+
757803
match prog {
758804
Ok(prog) => {
759805
fn escape_string(s: &[u8]) -> String {

0 commit comments

Comments
 (0)