Skip to content

Commit f7a8f44

Browse files
committed
Rollup merge of rust-lang#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 rust-lang#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 rust-lang#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 rust-lang#38878.
2 parents f779114 + 993eae1 commit f7a8f44

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ matrix:
4545
RUST_CHECK_TARGET=check
4646
RUST_CONFIGURE_ARGS=--build=x86_64-apple-darwin
4747
SRC=.
48+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
4849
os: osx
4950
osx_image: xcode8.2
5051
install: &osx_install_sccache >
@@ -54,6 +55,7 @@ matrix:
5455
RUST_CHECK_TARGET=check
5556
RUST_CONFIGURE_ARGS=--build=i686-apple-darwin
5657
SRC=.
58+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
5759
os: osx
5860
osx_image: xcode8.2
5961
install: *osx_install_sccache
@@ -63,6 +65,7 @@ matrix:
6365
RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-extended"
6466
SRC=.
6567
DEPLOY=1
68+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
6669
os: osx
6770
osx_image: xcode8.2
6871
install: >
@@ -75,6 +78,7 @@ matrix:
7578
RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-extended"
7679
SRC=.
7780
DEPLOY=1
81+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
7882
os: osx
7983
osx_image: xcode8.2
8084
install: *osx_install_sccache
@@ -89,6 +93,7 @@ matrix:
8993
RUST_CONFIGURE_ARGS="--enable-extended"
9094
SRC=.
9195
DEPLOY_ALT=1
96+
RUSTC_RETRY_LINKER_ON_SEGFAULT=1
9297
os: osx
9398
osx_image: xcode8.2
9499
install: *osx_install_sccache

src/librustc_trans/back/link.rs

Lines changed: 47 additions & 1 deletion
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)