mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-18 10:43:12 +00:00
Add libstd and libcore Cargo features "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.
This commit is contained in:
parent
f1e2fa8f04
commit
fdef3848a0
@ -21,3 +21,7 @@ path = "../libcore/benches/lib.rs"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.5"
|
rand = "0.5"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# Make panics and failed asserts immediately abort without formatting any message
|
||||||
|
panic_immediate_abort = []
|
||||||
|
@ -39,9 +39,15 @@
|
|||||||
use fmt;
|
use fmt;
|
||||||
use panic::{Location, PanicInfo};
|
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"]
|
#[lang = "panic"]
|
||||||
pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
|
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
|
// Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
|
||||||
// reduce size overhead. The format_args! macro uses str's Display trait to
|
// reduce size overhead. The format_args! macro uses str's Display trait to
|
||||||
// write expr, which calls Formatter::pad, which must accommodate string
|
// 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))
|
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"]
|
#[lang = "panic_bounds_check"]
|
||||||
fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
|
fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
|
||||||
index: usize, len: usize) -> ! {
|
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 {}",
|
panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}",
|
||||||
len, index), file_line_col)
|
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)) -> ! {
|
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
|
// 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
|
#[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
|
@ -47,6 +47,9 @@ backtrace = []
|
|||||||
panic-unwind = ["panic_unwind"]
|
panic-unwind = ["panic_unwind"]
|
||||||
profiler = ["profiler_builtins"]
|
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
|
# 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
|
# interoperate with the host environment. Currently not well documented and
|
||||||
# requires rebuilding the standard library to use it.
|
# requires rebuilding the standard library to use it.
|
||||||
|
@ -334,9 +334,15 @@ pub fn rust_begin_panic(info: &PanicInfo) -> ! {
|
|||||||
#[unstable(feature = "libstd_sys_internals",
|
#[unstable(feature = "libstd_sys_internals",
|
||||||
reason = "used by the panic! macro",
|
reason = "used by the panic! macro",
|
||||||
issue = "0")]
|
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,
|
pub fn begin_panic_fmt(msg: &fmt::Arguments,
|
||||||
file_line_col: &(&'static str, u32, u32)) -> ! {
|
file_line_col: &(&'static str, u32, u32)) -> ! {
|
||||||
|
if cfg!(feature = "panic_immediate_abort") {
|
||||||
|
unsafe { intrinsics::abort() }
|
||||||
|
};
|
||||||
|
|
||||||
let (file, line, col) = *file_line_col;
|
let (file, line, col) = *file_line_col;
|
||||||
let info = PanicInfo::internal_constructor(
|
let info = PanicInfo::internal_constructor(
|
||||||
Some(msg),
|
Some(msg),
|
||||||
@ -398,8 +404,15 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! {
|
|||||||
reason = "used by the panic! macro",
|
reason = "used by the panic! macro",
|
||||||
issue = "0")]
|
issue = "0")]
|
||||||
#[cfg_attr(not(test), lang = "begin_panic")]
|
#[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)) -> ! {
|
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.
|
// 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,
|
// 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
|
// but then again we're not really ready for panic on OOM anyway. If
|
||||||
|
Loading…
Reference in New Issue
Block a user