-
Notifications
You must be signed in to change notification settings - Fork 14.1k
core::intrinsics::abort: Terminate with __fastfail on Windows #149780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
This is what we do on all targets. It seems odd to do something special here for Windows only. If we want the intrinsic to do something OS-specific, we should make it so that all OSes benefit from that. It is also rather unprecedented to do anything OS-specific in Cc @rust-lang/libs |
|
Well if you ignore |
|
The job Click to see the possible cause of the failure (guessed by this bot) |
We have an intrinsic that declares it does something OS-specific by being described as "Aborts the execution of the process.", which is an inherently OS-specific concept and not something the compiler has to or should implement. Here I'd argue that
|
|
For better or worse, aborting execution is an OS-independent capability in MIR. The intrinsic is just one of the ways it gets invoked; there is also am Abort terminator, and there might be other places in codegen that invoke the same operation.
If LLVM cannot generate the right instructions for us, then at the very least we should do something consistent on our side.
Is this worth bringing up with LLVM, to fix whatever intrinsic we are using for abort() so that it behaves as intended on Windows?
|
|
The intrinsic is currently implemented in terms of llvm's I don't think llvm has an abort. At least I couldn't find one. |
|
So you would argue that what LLVM does on Windows is a reasonable implementation for "trap", it's just not what we want for "abort"?
|
|
Indeed. |
|
Yes. I would expect an abort to immediately abort the process rather than raising an exception (unless there's no reasonable alternative). On the other hand raising an exception is a reasonable implementation of trap. Somewhat related is #149708 but there the exception can only be caught outside of the rust program. |
|
Okay. But then we should use that consistently for all implementations of "abort", not just the intrinsic. We should probably rename the
Then I would suggest you entirely undo the changes in
|
|
I think there may be some unfortunate choices of terminology here, but it's not super obvious to me that this is really a desirable/necessary change in terms of how the abort intrinsic is used. If we take Also worth noting that this also sends a SIGILL signal on other OSes, so I'm not sure why Windows specifically needs divergent behavior. |
|
The And personally I would expect, from a libs pov, for |
| /// 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entire doc comment only applies to the Windows version of this function. So doc.rust-lang.org would no longer show it.
SIGILL doesn't unwind the stack, while Windows exceptions do unwind the stack through SEH. As such SIGILL only runs an explicitly registered signal handler, while Windows exceptions as I understand it run all |
I guess in that case I'd wonder whether this difference in behavior would be a compelling reason to change what llvm.trap does on Windows? |
|
Trapping is much more generic in usage than specifically aborting the process as fast as possible, which is what we want and already do in |
That's not the only thing Does __fastfail do that? |
Most direct uses of |
Yes, see the documentation for
|
|
That seems to make it a reasonable call for LLVM to use it as an implementation of |
Currently,
std::process::abortaborts the process via__fastfailon Windows, which is the preferred way of terminating processes since Windows 8 as it doesn't go through exception handlers. However,core::intrinsics::abortdoes not, and terminates by executing an illegal instruction, which causesSTATUS_ILLEGAL_INSTRUCTIONto be thrown. This PR removes that discrepancy and makescore::intrinsics::abortuse__fastfailon Windows.Implementation-wise, this is currently done by having
core::intrinsics::abortcall a function incore::osif on Windows and on one of the supported architectures. Unfortunately, this means there is now a function that, depending on the target, isn't an intrinsic inside theintrinsicsmodule, which isn't great. I've chosen to implement it like that anyway to gather feedback on better approaches - my initial idea was to lower it to a inline asm block withinrustc_codegen_ssa, as none of the backends has an intrinsic for fastfail and we thus have to manually spell out the assembly anyway, but there didn't seem to be a good reason for manually generating an inline assembly block in MIR intrinsic handling as opposed to just writing it as an asm block in the first place, as has been done insidestd.