Skip to content

Commit f0458c2

Browse files
committed
Auto merge of #55011 - vi:panic_immediate_abort, r=alexcrichton
Add libstd Cargo feature "panic_immediate_abort" It stop asserts and panics from libstd to automatically include string output and formatting code. Use case: developing static executables smaller than 50 kilobytes, where usual formatting code is excessive while keeping debuggability in debug mode. May resolve #54981.
2 parents d48ab69 + f18a8c6 commit f0458c2

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

src/libcore/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ path = "../libcore/benches/lib.rs"
2121

2222
[dev-dependencies]
2323
rand = "0.5"
24+
25+
[features]
26+
# Make panics and failed asserts immediately abort without formatting any message
27+
panic_immediate_abort = []

src/libcore/panicking.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,16 @@
3939
use fmt;
4040
use panic::{Location, PanicInfo};
4141

42-
#[cold] #[inline(never)] // this is the slow path, always
42+
#[cold]
43+
// never inline unless panic_immediate_abort to avoid code
44+
// bloat at the call sites as much as possible
45+
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
4346
#[lang = "panic"]
4447
pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
48+
if cfg!(feature = "panic_immediate_abort") {
49+
unsafe { super::intrinsics::abort() }
50+
}
51+
4552
// Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
4653
// reduce size overhead. The format_args! macro uses str's Display trait to
4754
// write expr, which calls Formatter::pad, which must accommodate string
@@ -52,16 +59,27 @@ pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
5259
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line, col))
5360
}
5461

55-
#[cold] #[inline(never)]
62+
#[cold]
63+
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
5664
#[lang = "panic_bounds_check"]
5765
fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
5866
index: usize, len: usize) -> ! {
67+
if cfg!(feature = "panic_immediate_abort") {
68+
unsafe { super::intrinsics::abort() }
69+
}
70+
5971
panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}",
6072
len, index), file_line_col)
6173
}
6274

63-
#[cold] #[inline(never)]
75+
#[cold]
76+
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
77+
#[cfg_attr( feature="panic_immediate_abort" ,inline)]
6478
pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
79+
if cfg!(feature = "panic_immediate_abort") {
80+
unsafe { super::intrinsics::abort() }
81+
}
82+
6583
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
6684
#[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
6785
extern "Rust" {

src/libstd/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ backtrace = []
4747
panic-unwind = ["panic_unwind"]
4848
profiler = ["profiler_builtins"]
4949

50+
# Make panics and failed asserts immediately abort without formatting any message
51+
panic_immediate_abort = ["core/panic_immediate_abort"]
52+
5053
# An off-by-default feature which enables a linux-syscall-like ABI for libstd to
5154
# interoperate with the host environment. Currently not well documented and
5255
# requires rebuilding the standard library to use it.

src/libstd/panicking.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,17 @@ pub fn rust_begin_panic(info: &PanicInfo) -> ! {
334334
#[unstable(feature = "libstd_sys_internals",
335335
reason = "used by the panic! macro",
336336
issue = "0")]
337-
#[inline(never)] #[cold]
337+
#[cold]
338+
// If panic_immediate_abort, inline the abort call,
339+
// otherwise avoid inlining because of it is cold path.
340+
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
341+
#[cfg_attr( feature="panic_immediate_abort" ,inline)]
338342
pub fn begin_panic_fmt(msg: &fmt::Arguments,
339343
file_line_col: &(&'static str, u32, u32)) -> ! {
344+
if cfg!(feature = "panic_immediate_abort") {
345+
unsafe { intrinsics::abort() }
346+
}
347+
340348
let (file, line, col) = *file_line_col;
341349
let info = PanicInfo::internal_constructor(
342350
Some(msg),
@@ -398,8 +406,15 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! {
398406
reason = "used by the panic! macro",
399407
issue = "0")]
400408
#[cfg_attr(not(test), lang = "begin_panic")]
401-
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
409+
// never inline unless panic_immediate_abort to avoid code
410+
// bloat at the call sites as much as possible
411+
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
412+
#[cold]
402413
pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! {
414+
if cfg!(feature = "panic_immediate_abort") {
415+
unsafe { intrinsics::abort() }
416+
}
417+
403418
// Note that this should be the only allocation performed in this code path.
404419
// Currently this means that panic!() on OOM will invoke this code path,
405420
// but then again we're not really ready for panic on OOM anyway. If

0 commit comments

Comments
 (0)