Skip to content
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

Use libc::abort, not intrinsics::abort, in rtabort! #31457

Merged
merged 1 commit into from
May 23, 2016

Conversation

lambda
Copy link
Contributor

@lambda lambda commented Feb 6, 2016

intrinsics::abort compiles down to an illegal instruction, which on
Unix-like platforms causes the process to be killed with SIGILL. A more
appropriate way to kill the process would be SIGABRT; this indicates
better that the runtime has explicitly aborted, rather than some kind of
compiler bug or architecture mismatch that SIGILL might indicate.

For rtassert!, replace this with libc::abort. libc::abort raises
SIGABRT, but is defined to do so in such a way that it will terminate
the process even if SIGABRT is currently masked or caught by a signal
handler that returns.

On non-Unix platforms, retain the existing behavior. On Windows we
prefer to avoid depending on the C runtime, and we need a fallback for
any other platforms that may be defined. An alternative on Windows
would be to call TerminateProcess, but this seems less essential than
switching to using SIGABRT on Unix-like platforms, where it is common
for the process-killing signal to be printed out or logged.

This is a [breaking-change] for any code that depends on the exact
signal raised to abort a process via rtabort!

cc #31273
cc #31333

@rust-highfive
Copy link
Collaborator

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

@lambda
Copy link
Contributor Author

lambda commented Feb 6, 2016

As discussed in #31333, it may be more appropriate to abort using SIGABRT rather than SIGILL. As @brson said:

My preference is for all aborts to be the same, and would prefer this to be an rtabort!. If it would be more proper to terminate with SIGABORT than SIGILL let's do that for all aborts, not just this one (but in a separate PR).

This only turns rtabort! into SIGABRT, and only on Unix; on Windows, @alexcrichton mentioned that we want to avoid the C runtime, and it seems like less of a win there. Also, I believe that we don't have the ability to use libc::abort in lower-level libraries that call intrinsics::abort, so that remains implemented as before.

@retep998
Copy link
Member

retep998 commented Feb 6, 2016

The proper mechanism on Windows is actually __fastfail which is an intrinsic https://msdn.microsoft.com/en-us/library/dn774154.aspx

@retep998
Copy link
Member

retep998 commented Feb 7, 2016

Alternatively we can call RaiseFailFastException which is a full function call rather than a simple instruction.

@alexcrichton
Copy link
Member

lgtm

@lambda
Copy link
Contributor Author

lambda commented Feb 7, 2016

@retep998 Yeah, looks like one of those might be appropriate. Since I don't have a Windows box and I don't know how the current mechanism or those behave on Windows, it's probably more appropriate for someone else who does have such access to send a patch for switching to those on Windows if appropriate.

@retep998
Copy link
Member

retep998 commented Feb 8, 2016

Here is the Windows implementation.

    unsafe {
        asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT
        std::intrinsics::unreachable();
    }

@brson
Copy link
Contributor

brson commented Feb 9, 2016

@bors r+ I'll submit a windows implementation in a bit.

@bors
Copy link
Contributor

bors commented Feb 9, 2016

📌 Commit de250e5 has been approved by brson

@brson brson added the relnotes Marks issues that should be documented in the release notes of the next release. label Feb 9, 2016
@brson
Copy link
Contributor

brson commented Feb 9, 2016

@bors r- I want to wait until we decide on #31519

@alexcrichton
Copy link
Member

Hey @lambda, sorry for the delay! With the landing of #32900 we're already starting to diverge in terms of what abort means on each platform, so I think it's fine now to land this for the Unix side of things and then we can fixup the Windows side later. It seems like it's actually somewhat difficult to find a canonical way on Windows that indicates "the runtime wanted to abort" that works everywhere!

Would you be ok updating this patch with two pieces?

  • A comment indicating why Unix/Windows differ
  • A bit of a refactoring to share at least the dumb_print code and only differ in the abort code

intrinsics::abort compiles down to an illegal instruction, which on
Unix-like platforms causes the process to be killed with SIGILL.  A more
appropriate way to kill the process would be SIGABRT; this indicates
better that the runtime has explicitly aborted, rather than some kind of
compiler bug or architecture mismatch that SIGILL might indicate.

For rtassert!, replace this with libc::abort.  libc::abort raises
SIGABRT, but is defined to do so in such a way that it will terminate
the process even if SIGABRT is currently masked or caught by a signal
handler that returns.

On non-Unix platforms, retain the existing behavior.  On Windows we
prefer to avoid depending on the C runtime, and we need a fallback for
any other platforms that may be defined.  An alternative on Windows
would be to call TerminateProcess, but this seems less essential than
switching to using SIGABRT on Unix-like platforms, where it is common
for the process-killing signal to be printed out or logged.

This is a [breaking-change] for any code that depends on the exact
signal raised to abort a process via rtabort!

cc rust-lang#31273
cc rust-lang#31333
@lambda
Copy link
Contributor Author

lambda commented May 23, 2016

@alexcrichton Should be done in my most recent push.

I also rebased the Windows patch from @brson from #31519 in another branch in my repo, in case we want to also apply that. I could push that to this PR if we want to merge both at once, or I could push that separately after this lands. I'm reasonably convinced by the arguments from @retep998 that that's the right thing to do on Windows, but I'm not a Windows user and it's been a while since I've done serious Windows development, so I will defer to those with more experience on that platform.

@retep998
Copy link
Member

I'm still of the opinion that __fastfail is the better choice for Windows because on newer Windows it causes the process to die loudly with an uncatchable exception, and on older Windows it is equivalent to intrinsics::abort in that it still causes an exception just with a different error code.

@alexcrichton
Copy link
Member

@bors: r+ cfc3865

Thanks @lambda! Sending #31519 as a new PR also seems fine to me.

@bors
Copy link
Contributor

bors commented May 23, 2016

⌛ Testing commit cfc3865 with merge 6e45564...

bors added a commit that referenced this pull request May 23, 2016
Use libc::abort, not intrinsics::abort, in rtabort!

intrinsics::abort compiles down to an illegal instruction, which on
Unix-like platforms causes the process to be killed with SIGILL.  A more
appropriate way to kill the process would be SIGABRT; this indicates
better that the runtime has explicitly aborted, rather than some kind of
compiler bug or architecture mismatch that SIGILL might indicate.

For rtassert!, replace this with libc::abort.  libc::abort raises
SIGABRT, but is defined to do so in such a way that it will terminate
the process even if SIGABRT is currently masked or caught by a signal
handler that returns.

On non-Unix platforms, retain the existing behavior.  On Windows we
prefer to avoid depending on the C runtime, and we need a fallback for
any other platforms that may be defined.  An alternative on Windows
would be to call TerminateProcess, but this seems less essential than
switching to using SIGABRT on Unix-like platforms, where it is common
for the process-killing signal to be printed out or logged.

This is a [breaking-change] for any code that depends on the exact
signal raised to abort a process via rtabort!

cc #31273
cc #31333
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Marks issues that should be documented in the release notes of the next release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants