Std::process::abort should be implemented through exit(3) on Win32 mode

According to this issue: std::process::abort from FFI does not abort. · Issue #93276 · rust-lang/rust · GitHub

std::process::abort now implemented throught __fastfail, which dont terminate program on Win7 and earlier.
On Win7 __fastfail throws an exception, and WndProc on Win32 will... suppress it! And panicked program will enter WndProc with brocken state and print error message to console infinite times. So if you compile program in "panic=abort" mode, you will no abort.
Currently the only way to terminate program with std is use unwinding mode and catch_unwind the panic on the top of WndProc and write exit(3) in panic handler. But unwinding mode is a lot of overhead and boilerplate inside executable. So on target i686-windows-* panic should be implemented through exit(3)

2 Likes

What about trying fastfail first and if it unwinds doing exit(3)?

  1. Do you mean exit(3) as in man 3 exit or as in "call the C library function exit with argument 3"? If the former, what exit code should be used and why? If the latter, why exit code 3 specifically (and not, for instance, 0xC0000409 as is documented for __fastfail?)

  2. As best I can tell from skimming MSDN, the situation you describe can only occur

    • when __fastfail is used inside a window procedure
    • and the process is 32-bit but the OS is 64-bit
    • and the OS is Windows 7 or earlier

    This seems like a rare situation, that should not stop std::process::abort from using __fastfail in the general case.

Is there perhaps, instead, something Rust's runtime could do to make old versions of Windows not suppress SEH exceptions thrown out of window procedures by 32-bit processes? Or maybe it doesn't even go in std, but instead, in the hypothetical crate that helps you write Win32 GUI programs without having to use as much unsafe as you did in the test program you showed in the bug you linked to.

What about trying fastfail first and if it unwinds doing exit(3) ?

Rust catch_unwind can catch only Rust's exception, so I dont know the way to check other exceptions. So I dont see the way to implement this variant.

I mean std::process::exit(3). The number 3 was got from here: https://github.com/huangqinjin/ucrt/blob/faa22ac4e1e94c2832d48ff2edab4da3e4cfea31/startup/abort.cpp#L89

But the exact value of exit code does not matter for me. Any value (except 0) is good, if program will terminate.

Yes, it is. This situation is not rare. I compile programs in x32 mode, because some users has old computers, and I want to make the target audience wider. Also if I publish x32 and x64 versions, some users will run x32 version on x64 system, and there is no way to prevent it.

On library level the easiest way is to handle windows32 case here: https://github.com/rust-lang/rust/blob/master/library/std/src/sys/windows/mod.rs#L291, I can make PR if it is necessary. On user level I cant catch exceptions, I can catch only Rust panics in unwinding mode, but "panic=abort" mode is still broken.

I think the suggestion is to implement something like this: rust/stack_overflow.rs at 686663a49e57870c78a4cd047f23a44175fc67a4 · rust-lang/rust · GitHub

But for EXCEPTION_ACCESS_VIOLATION. So that it would call TerminateProcess when the application is 32bit and the OS is 64bit Windows 7.

"Rust on Win32 needs some way to catch arbitrary SEH exceptions" does seem like a valid feature request.

  1. There could be a compiler intrinsic for this used by libstd.
  2. I think you can set a vectored exception handler which exits when invoked. (edit: already suggested by chrisd)

It will be ok, but I think, this way will be something like very platform-specific stuff, so I prefer to see it inside std lib abort implementation.

I think, first variant (when intrinsic used inside abort's implementation) will be better, because this intrinsic should be very platform-specific. It would be better to allow user to use the minimal possible count of platform-specific intrinsics.

The vectored exception handler can set by std::process::abort just before trying to raise a fastfail exception. No need for the user to do this.

1 Like

I think, I can agree with this option

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.