Skip to content

Commit 533afea

Browse files
committed
Improve diagnostic for linker abort exit code 0xc0000409 (STATUS_STACK_BUFFER_OVERRUN)
Tweak __fastfail termination note text to clarify behavior Move __fastfail termination diagnostic emission outside MSVC toolchain check to enable testing Since the ui tests cannot satisfy the MSVC toolchain check - hence making this behavior untestable. Add UI test for __fastfail termination (0xc0000409) linker diagnostic note Fix formatting
1 parent d41e12f commit 533afea

File tree

5 files changed

+42
-0
lines changed

5 files changed

+42
-0
lines changed

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented y
176176
177177
codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error}
178178
179+
codegen_ssa_link_exe_fastfail_abort_note = This may occur when using the MSVC toolchain on Windows and can be caused by `__fastfail` termination, rather than necessarily indicating a stack buffer overrun.
180+
181+
codegen_ssa_link_exe_fastfail_status = 0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN`
182+
179183
codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error
180184
181185
codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,13 @@ fn link_natively(
872872
// is not a Microsoft LNK error then suggest a way to fix or
873873
// install the Visual Studio build tools.
874874
if let Some(code) = prog.status.code() {
875+
// 0xc0000409 (`STATUS_STACK_BUFFER_OVERRUN`) is also used by `abort()` via `__fastfail` on Windows. Not necessarily a buffer overrun.
876+
// See <https://devblogs.microsoft.com/oldnewthing/20190108-00/?p=100655>
877+
const STATUS_STACK_BUFFER_OVERRUN: i32 = 0xC0000409u32 as i32; // = -1073740791
878+
if code == STATUS_STACK_BUFFER_OVERRUN {
879+
sess.dcx().emit_note(errors::LinkExeFastFailAbort);
880+
}
881+
875882
// All Microsoft `link.exe` linking ror codes are
876883
// four digit numbers in the range 1000 to 9999 inclusive
877884
if is_msvc_link_exe && (code < 1000 || code > 9999) {
@@ -880,6 +887,7 @@ fn link_natively(
880887
windows_registry::find_tool(&sess.target.arch, "link.exe").is_some();
881888

882889
sess.dcx().emit_note(errors::LinkExeUnexpectedError);
890+
883891
if is_vs_installed && has_linker {
884892
// the linker is broken
885893
sess.dcx().emit_note(errors::RepairVSBuildTools);

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,11 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
543543
#[diag(codegen_ssa_link_exe_unexpected_error)]
544544
pub(crate) struct LinkExeUnexpectedError;
545545

546+
#[derive(Diagnostic)]
547+
#[diag(codegen_ssa_link_exe_fastfail_status)]
548+
#[note(codegen_ssa_link_exe_fastfail_abort_note)]
549+
pub(crate) struct LinkExeFastFailAbort;
550+
546551
#[derive(Diagnostic)]
547552
#[diag(codegen_ssa_repair_vs_build_tools)]
548553
pub(crate) struct RepairVSBuildTools;

tests/ui/linking/auxiliary/link.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Dummy linker implementation simulating __fastfail termination
2+
// See <https://devblogs.microsoft.com/oldnewthing/20190108-00/?p=100655>
3+
fn main() {
4+
const STATUS_STACK_BUFFER_OVERRUN: i32 = 0xC0000409u32 as i32;
5+
std::process::exit(STATUS_STACK_BUFFER_OVERRUN);
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//@ build-fail
2+
//@ only-windows The abnormal behaviour may be observed only on Windows using the MSVC linker
3+
//@ only-msvc
4+
5+
//@ ignore-cross-compile because aux-bin does not yet support it
6+
//@ aux-bin: link.rs
7+
// Dummy linker that will always exit as if like with __fastfail abort()
8+
9+
//@ compile-flags: -Clinker={{build-base}}\linking\linker-fastfail-abort\auxiliary\bin\link.exe -Ctarget-feature=+crt-static
10+
11+
// Since the error notes are too verbose
12+
//@ dont-check-compiler-stderr
13+
//@ dont-require-annotations: NOTE
14+
15+
//~? ERROR linking with `$TEST_BUILD_DIR/auxiliary/bin/link.exe` failed: exit code: 0xc0000409
16+
//~? NOTE 0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN`
17+
//~? NOTE This may occur when using the MSVC toolchain on Windows and can be caused by `__fastfail` termination, rather than necessarily indicating a stack buffer overrun.
18+
19+
fn main() {}

0 commit comments

Comments
 (0)