diff options
| author | bors <bors@rust-lang.org> | 2016-05-22 23:14:11 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-05-22 23:14:11 -0700 |
| commit | 6e455640950c4e8cb8bff919edb4854fcf7773ca (patch) | |
| tree | 72c06cdbaf5c6dc34fc76b0c82c9e8d76a22ec4d /src/libstd | |
| parent | e24d621fcacf59fa8ecc1c1af1c4adeded4bddee (diff) | |
| parent | cfc386583291c8868d093d07431a57a20e69c944 (diff) | |
| download | rust-6e455640950c4e8cb8bff919edb4854fcf7773ca.tar.gz rust-6e455640950c4e8cb8bff919edb4854fcf7773ca.zip | |
Auto merge of #31457 - lambda:rtabort-use-libc-abort, r=alexcrichton
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
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/sys/common/util.rs | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/libstd/sys/common/util.rs b/src/libstd/sys/common/util.rs index b7a6b7650d5..1df511a8818 100644 --- a/src/libstd/sys/common/util.rs +++ b/src/libstd/sys/common/util.rs @@ -10,7 +10,6 @@ use env; use fmt; -use intrinsics; use io::prelude::*; use sync::atomic::{self, Ordering}; use sys::stdio::Stderr; @@ -34,9 +33,32 @@ pub fn dumb_print(args: fmt::Arguments) { let _ = Stderr::new().map(|mut stderr| stderr.write_fmt(args)); } +// On Unix-like platforms, libc::abort will unregister signal handlers +// including the SIGABRT handler, preventing the abort from being blocked, and +// fclose streams, with the side effect of flushing them so libc bufferred +// output will be printed. Additionally the shell will generally print a more +// understandable error message like "Abort trap" rather than "Illegal +// instruction" that intrinsics::abort would cause, as intrinsics::abort is +// implemented as an illegal instruction. +#[cfg(unix)] +unsafe fn abort_internal() -> ! { + use libc; + libc::abort() +} + +// On Windows, we want to avoid using libc, and there isn't a direct +// equivalent of libc::abort. The __failfast intrinsic may be a reasonable +// substitute, but desireability of using it over the abort instrinsic is +// debateable; see https://github.com/rust-lang/rust/pull/31519 for details. +#[cfg(not(unix))] +unsafe fn abort_internal() -> ! { + use intrinsics; + intrinsics::abort() +} + pub fn abort(args: fmt::Arguments) -> ! { dumb_print(format_args!("fatal runtime error: {}\n", args)); - unsafe { intrinsics::abort(); } + unsafe { abort_internal(); } } #[allow(dead_code)] // stack overflow detection not enabled on all platforms |
