about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/Cargo.toml4
-rw-r--r--src/libcore/panicking.rs24
-rw-r--r--src/libstd/Cargo.toml3
-rw-r--r--src/libstd/panicking.rs17
4 files changed, 43 insertions, 5 deletions
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index 0b01cfc488b..7fd61f07d5e 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -21,3 +21,7 @@ path = "../libcore/benches/lib.rs"
 
 [dev-dependencies]
 rand = "0.5"
+
+[features]
+# Make panics and failed asserts immediately abort without formatting any message
+panic_immediate_abort = []
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 58407de9566..67c0b6ada90 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -39,9 +39,15 @@
 use fmt;
 use panic::{Location, PanicInfo};
 
-#[cold] #[inline(never)] // this is the slow path, always
+#[cold]
+// inline(never) is required even in panic_immediate_abort mode, lest linker error
+#[inline(never)]
 #[lang = "panic"]
 pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    };
+
     // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
     // reduce size overhead. The format_args! macro uses str's Display trait to
     // write expr, which calls Formatter::pad, which must accommodate string
@@ -52,16 +58,28 @@ pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
     panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line, col))
 }
 
-#[cold] #[inline(never)]
+#[cold]
+// inline(never) is required even in panic_immediate_abort mode, lest linker error
+#[inline(never)]
 #[lang = "panic_bounds_check"]
 fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
                      index: usize, len: usize) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    };
+
     panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}",
                            len, index), file_line_col)
 }
 
-#[cold] #[inline(never)]
+#[cold]
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cfg_attr(    feature="panic_immediate_abort" ,inline)]
 pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    };
+
     // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
     #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
     extern "Rust" {
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 2b1d515c83b..c1446218367 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -47,6 +47,9 @@ backtrace = []
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
 
+# Make panics and failed asserts immediately abort without formatting any message
+panic_immediate_abort = ["core/panic_immediate_abort"]
+
 # An off-by-default feature which enables a linux-syscall-like ABI for libstd to
 # interoperate with the host environment. Currently not well documented and
 # requires rebuilding the standard library to use it.
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index a0590a800d3..29a0b3feefd 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -334,9 +334,15 @@ pub fn rust_begin_panic(info: &PanicInfo) -> ! {
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
            issue = "0")]
-#[inline(never)] #[cold]
+#[cold]
+#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cfg_attr(    feature="panic_immediate_abort" ,inline)]
 pub fn begin_panic_fmt(msg: &fmt::Arguments,
                        file_line_col: &(&'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { intrinsics::abort() }
+    };
+
     let (file, line, col) = *file_line_col;
     let info = PanicInfo::internal_constructor(
         Some(msg),
@@ -398,8 +404,15 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! {
            reason = "used by the panic! macro",
            issue = "0")]
 #[cfg_attr(not(test), lang = "begin_panic")]
-#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
+// avoid code bloat at the call sites as much as possible
+// inline(never) is required even in panic_immediate_abort mode, lest linker error
+#[inline(never)]
+#[cold]
 pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { intrinsics::abort() }
+    };
+
     // Note that this should be the only allocation performed in this code path.
     // Currently this means that panic!() on OOM will invoke this code path,
     // but then again we're not really ready for panic on OOM anyway. If