Skip to content

Commit de08931

Browse files
committed
core::intrinsics::abort: Terminate with __fastfail on Windows
1 parent fa1f706 commit de08931

File tree

7 files changed

+101
-30
lines changed

7 files changed

+101
-30
lines changed

library/core/src/intrinsics/mod.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,38 @@ pub fn rustc_peek<T>(_: T) -> T;
362362
/// on most platforms.
363363
/// On Unix, the
364364
/// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
365-
/// `SIGBUS`. The precise behavior is not guaranteed and not stable.
365+
/// `SIGBUS`.
366+
/// On Windows, the
367+
/// process will use `__fastfail` to terminate the process, which will terminate the process
368+
/// immediately without running any in-process exception handlers. In earlier versions of Windows,
369+
/// this sequence of instructions will be treated as an access violation, which
370+
/// will still terminate the process but might run some exception handlers.
371+
///
372+
/// The precise behavior is not guaranteed and not stable.
373+
374+
#[cfg(all(
375+
not(miri),
376+
windows,
377+
any(
378+
any(target_arch = "x86", target_arch = "x86_64"),
379+
all(target_arch = "arm", target_feature = "thumb-mode"),
380+
any(target_arch = "aarch64", target_arch = "arm64ec")
381+
)
382+
))]
383+
#[rustc_nounwind]
384+
pub fn abort() -> ! {
385+
crate::os::windows::fastfail();
386+
}
387+
388+
#[cfg(not(all(
389+
not(miri),
390+
windows,
391+
any(
392+
any(target_arch = "x86", target_arch = "x86_64"),
393+
all(target_arch = "arm", target_feature = "thumb-mode"),
394+
any(target_arch = "aarch64", target_arch = "arm64ec")
395+
)
396+
)))]
366397
#[rustc_nounwind]
367398
#[rustc_intrinsic]
368399
pub fn abort() -> !;

library/core/src/os/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! OS-specific functionality.
22
3-
#![unstable(feature = "darwin_objc", issue = "145496")]
3+
#![cfg_attr(target_vendor = "apple", unstable(feature = "darwin_objc", issue = "145496"))]
4+
#![cfg_attr(not(target_vendor = "apple"), unstable(issue = "none", feature = "std_internals"))]
45

56
#[cfg(all(
67
doc,
@@ -22,3 +23,24 @@ pub mod darwin {}
2223
)))]
2324
#[cfg(any(target_vendor = "apple", doc))]
2425
pub mod darwin;
26+
27+
#[cfg(all(
28+
doc,
29+
any(
30+
all(target_arch = "wasm32", not(target_os = "wasi")),
31+
all(target_vendor = "fortanix", target_env = "sgx")
32+
)
33+
))]
34+
#[unstable(issue = "none", feature = "std_internals")]
35+
pub mod windows {}
36+
37+
// windows
38+
#[cfg(not(all(
39+
doc,
40+
any(
41+
all(target_arch = "wasm32", not(target_os = "wasi")),
42+
all(target_vendor = "fortanix", target_env = "sgx")
43+
)
44+
)))]
45+
#[cfg(any(windows, doc))]
46+
pub mod windows;

library/core/src/os/windows/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//! Platform-specific extensions to `core` for Windows platforms.
2+
3+
#![unstable(issue = "none", feature = "std_internals")]
4+
5+
use crate::cfg_select;
6+
7+
const FAST_FAIL_FATAL_APP_EXIT: u32 = 7u32;
8+
9+
/// Use `__fastfail` to abort the process
10+
///
11+
/// In Windows 8 and later, this will terminate the process immediately without
12+
/// running any in-process exception handlers. In earlier versions of Windows,
13+
/// this sequence of instructions will be treated as an access violation, which
14+
/// will still terminate the process but might run some exception handlers.
15+
///
16+
/// https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail
17+
#[cfg(all(
18+
not(miri),
19+
any(
20+
any(target_arch = "x86", target_arch = "x86_64"),
21+
all(target_arch = "arm", target_feature = "thumb-mode"),
22+
any(target_arch = "aarch64", target_arch = "arm64ec")
23+
)
24+
))]
25+
pub fn fastfail() -> ! {
26+
// SAFETY: These assembly instructions are always safe to call and will result in the documented behavior.
27+
unsafe {
28+
cfg_select! {
29+
any(target_arch = "x86", target_arch = "x86_64") => {
30+
core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
31+
}
32+
all(target_arch = "arm", target_feature = "thumb-mode") => {
33+
core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
34+
}
35+
any(target_arch = "aarch64", target_arch = "arm64ec") => {
36+
core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
37+
}
38+
_ => {}
39+
}
40+
}
41+
}

library/std/src/sys/pal/windows/c/bindings.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,6 @@ FACILITY_CODE
19701970
FACILITY_NT_BIT
19711971
FALSE
19721972
FARPROC
1973-
FAST_FAIL_FATAL_APP_EXIT
19741973
FD_SET
19751974
FILE_ACCESS_RIGHTS
19761975
FILE_ADD_FILE

library/std/src/sys/pal/windows/c/windows_sys.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,7 +2391,6 @@ pub type FACILITY_CODE = u32;
23912391
pub const FACILITY_NT_BIT: FACILITY_CODE = 268435456u32;
23922392
pub const FALSE: BOOL = 0i32;
23932393
pub type FARPROC = Option<unsafe extern "system" fn() -> isize>;
2394-
pub const FAST_FAIL_FATAL_APP_EXIT: u32 = 7u32;
23952394
#[repr(C)]
23962395
#[derive(Clone, Copy)]
23972396
pub struct FD_SET {
@@ -3647,7 +3646,6 @@ impl Default for XSAVE_FORMAT {
36473646
unsafe { core::mem::zeroed() }
36483647
}
36493648
}
3650-
36513649
#[cfg(target_arch = "arm")]
36523650
#[repr(C)]
36533651
pub struct WSADATA {

library/std/src/sys/pal/windows/mod.rs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -336,28 +336,7 @@ pub fn dur2timeout(dur: Duration) -> u32 {
336336
/// will still terminate the process but might run some exception handlers.
337337
///
338338
/// https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail
339-
#[cfg(not(miri))] // inline assembly does not work in Miri
340-
pub fn abort_internal() -> ! {
341-
unsafe {
342-
cfg_select! {
343-
any(target_arch = "x86", target_arch = "x86_64") => {
344-
core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
345-
}
346-
all(target_arch = "arm", target_feature = "thumb-mode") => {
347-
core::arch::asm!(".inst 0xDEFB", in("r0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
348-
}
349-
any(target_arch = "aarch64", target_arch = "arm64ec") => {
350-
core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
351-
}
352-
_ => {
353-
core::intrinsics::abort();
354-
}
355-
}
356-
}
357-
}
358-
359-
#[cfg(miri)]
360-
#[track_caller] // even without panics, this helps for Miri backtraces
339+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
361340
pub fn abort_internal() -> ! {
362341
crate::intrinsics::abort();
363342
}

src/tools/tidy/src/pal.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ const EXCEPTION_PATHS: &[&str] = &[
5454
// core::ffi contains platform-specific type and linkage configuration
5555
"library/core/src/ffi/mod.rs",
5656
"library/core/src/ffi/primitives.rs",
57-
"library/core/src/os", // Platform-specific public interfaces
58-
"library/std/src/sys", // Platform-specific code for std lives here.
59-
"library/std/src/os", // Platform-specific public interfaces
57+
"library/core/src/intrinsics/mod.rs", // `abort` has an in-library implementation on Windows
58+
"library/core/src/os", // Platform-specific public interfaces
59+
"library/std/src/sys", // Platform-specific code for std lives here.
60+
"library/std/src/os", // Platform-specific public interfaces
6061
// Temporary `std` exceptions
6162
// FIXME: platform-specific code should be moved to `sys`
6263
"library/std/src/io/stdio.rs",

0 commit comments

Comments
 (0)