From de0893156d3933ed652a6340270d201a82bf6757 Mon Sep 17 00:00:00 2001 From: George Tokmaji Date: Mon, 8 Dec 2025 14:19:32 +0100 Subject: [PATCH] core::intrinsics::abort: Terminate with __fastfail on Windows --- library/core/src/intrinsics/mod.rs | 33 ++++++++++++++- library/core/src/os/mod.rs | 24 ++++++++++- library/core/src/os/windows/mod.rs | 41 +++++++++++++++++++ .../std/src/sys/pal/windows/c/bindings.txt | 1 - .../std/src/sys/pal/windows/c/windows_sys.rs | 2 - library/std/src/sys/pal/windows/mod.rs | 23 +---------- src/tools/tidy/src/pal.rs | 7 ++-- 7 files changed, 101 insertions(+), 30 deletions(-) create mode 100644 library/core/src/os/windows/mod.rs diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index eed7076ddaf10..21d48b104c761 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -362,7 +362,38 @@ pub fn rustc_peek(_: T) -> T; /// on most platforms. /// On Unix, the /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or -/// `SIGBUS`. The precise behavior is not guaranteed and not stable. +/// `SIGBUS`. +/// On Windows, the +/// process will use `__fastfail` to terminate the process, which will terminate the process +/// immediately without running any in-process exception handlers. In earlier versions of Windows, +/// this sequence of instructions will be treated as an access violation, which +/// will still terminate the process but might run some exception handlers. +/// +/// The precise behavior is not guaranteed and not stable. + +#[cfg(all( + not(miri), + windows, + any( + any(target_arch = "x86", target_arch = "x86_64"), + all(target_arch = "arm", target_feature = "thumb-mode"), + any(target_arch = "aarch64", target_arch = "arm64ec") + ) +))] +#[rustc_nounwind] +pub fn abort() -> ! { + crate::os::windows::fastfail(); +} + +#[cfg(not(all( + not(miri), + windows, + any( + any(target_arch = "x86", target_arch = "x86_64"), + all(target_arch = "arm", target_feature = "thumb-mode"), + any(target_arch = "aarch64", target_arch = "arm64ec") + ) +)))] #[rustc_nounwind] #[rustc_intrinsic] pub fn abort() -> !; diff --git a/library/core/src/os/mod.rs b/library/core/src/os/mod.rs index 897f59f530ed0..89bbf78d54068 100644 --- a/library/core/src/os/mod.rs +++ b/library/core/src/os/mod.rs @@ -1,6 +1,7 @@ //! OS-specific functionality. -#![unstable(feature = "darwin_objc", issue = "145496")] +#![cfg_attr(target_vendor = "apple", unstable(feature = "darwin_objc", issue = "145496"))] +#![cfg_attr(not(target_vendor = "apple"), unstable(issue = "none", feature = "std_internals"))] #[cfg(all( doc, @@ -22,3 +23,24 @@ pub mod darwin {} )))] #[cfg(any(target_vendor = "apple", doc))] pub mod darwin; + +#[cfg(all( + doc, + any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") + ) +))] +#[unstable(issue = "none", feature = "std_internals")] +pub mod windows {} + +// windows +#[cfg(not(all( + doc, + any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") + ) +)))] +#[cfg(any(windows, doc))] +pub mod windows; diff --git a/library/core/src/os/windows/mod.rs b/library/core/src/os/windows/mod.rs new file mode 100644 index 0000000000000..e86d709a7feef --- /dev/null +++ b/library/core/src/os/windows/mod.rs @@ -0,0 +1,41 @@ +//! Platform-specific extensions to `core` for Windows platforms. + +#![unstable(issue = "none", feature = "std_internals")] + +use crate::cfg_select; + +const FAST_FAIL_FATAL_APP_EXIT: u32 = 7u32; + +/// Use `__fastfail` to abort the process +/// +/// In Windows 8 and later, this will terminate the process immediately without +/// running any in-process exception handlers. In earlier versions of Windows, +/// this sequence of instructions will be treated as an access violation, which +/// will still terminate the process but might run some exception handlers. +/// +/// https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail +#[cfg(all( + not(miri), + any( + any(target_arch = "x86", target_arch = "x86_64"), + all(target_arch = "arm", target_feature = "thumb-mode"), + any(target_arch = "aarch64", target_arch = "arm64ec") + ) +))] +pub fn fastfail() -> ! { + // SAFETY: These assembly instructions are always safe to call and will result in the documented behavior. + unsafe { + cfg_select! { + any(target_arch = "x86", target_arch = "x86_64") => { + core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); + } + all(target_arch = "arm", target_feature = "thumb-mode") => { + core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); + } + any(target_arch = "aarch64", target_arch = "arm64ec") => { + core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); + } + _ => {} + } + } +} diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index 9009aa09f48ed..88b2bea5739b5 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -1970,7 +1970,6 @@ FACILITY_CODE FACILITY_NT_BIT FALSE FARPROC -FAST_FAIL_FATAL_APP_EXIT FD_SET FILE_ACCESS_RIGHTS FILE_ADD_FILE diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index 98f277b33780c..75ba3b1b1efc9 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -2391,7 +2391,6 @@ pub type FACILITY_CODE = u32; pub const FACILITY_NT_BIT: FACILITY_CODE = 268435456u32; pub const FALSE: BOOL = 0i32; pub type FARPROC = Option isize>; -pub const FAST_FAIL_FATAL_APP_EXIT: u32 = 7u32; #[repr(C)] #[derive(Clone, Copy)] pub struct FD_SET { @@ -3647,7 +3646,6 @@ impl Default for XSAVE_FORMAT { unsafe { core::mem::zeroed() } } } - #[cfg(target_arch = "arm")] #[repr(C)] pub struct WSADATA { diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index a5f060080130f..e6ba2ff2b024b 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -336,28 +336,7 @@ pub fn dur2timeout(dur: Duration) -> u32 { /// will still terminate the process but might run some exception handlers. /// /// https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail -#[cfg(not(miri))] // inline assembly does not work in Miri -pub fn abort_internal() -> ! { - unsafe { - cfg_select! { - any(target_arch = "x86", target_arch = "x86_64") => { - core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); - } - all(target_arch = "arm", target_feature = "thumb-mode") => { - core::arch::asm!(".inst 0xDEFB", in("r0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); - } - any(target_arch = "aarch64", target_arch = "arm64ec") => { - core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack)); - } - _ => { - core::intrinsics::abort(); - } - } - } -} - -#[cfg(miri)] -#[track_caller] // even without panics, this helps for Miri backtraces +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn abort_internal() -> ! { crate::intrinsics::abort(); } diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index e5945a72d32a0..886df748d857a 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -54,9 +54,10 @@ const EXCEPTION_PATHS: &[&str] = &[ // core::ffi contains platform-specific type and linkage configuration "library/core/src/ffi/mod.rs", "library/core/src/ffi/primitives.rs", - "library/core/src/os", // Platform-specific public interfaces - "library/std/src/sys", // Platform-specific code for std lives here. - "library/std/src/os", // Platform-specific public interfaces + "library/core/src/intrinsics/mod.rs", // `abort` has an in-library implementation on Windows + "library/core/src/os", // Platform-specific public interfaces + "library/std/src/sys", // Platform-specific code for std lives here. + "library/std/src/os", // Platform-specific public interfaces // Temporary `std` exceptions // FIXME: platform-specific code should be moved to `sys` "library/std/src/io/stdio.rs",