summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-04-25 00:08:37 +0200
committerMatthias Krüger <matthias.krueger@famsik.de>2023-04-25 00:08:37 +0200
commit23a363821de3276747b27754bd0dd03a32991187 (patch)
tree48b153ca8446d82f0cbd887c37161e9201612918 /library
parentf54dbe6e3116a475f63b580884f07474239a0b25 (diff)
downloadrust-23a363821de3276747b27754bd0dd03a32991187.tar.gz
Revert "Report allocation errors as panics"
This reverts commit c9a6e41026d7aa27d897fb83e995447719753076.
Diffstat (limited to 'library')
-rw-r--r--library/alloc/Cargo.toml3
-rw-r--r--library/alloc/src/alloc.rs84
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/panicking.rs43
6 files changed, 27 insertions, 107 deletions
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 8975ba3f06b..95c07abf731 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -35,6 +35,3 @@ compiler-builtins-mem = ['compiler_builtins/mem']
compiler-builtins-c = ["compiler_builtins/c"]
compiler-builtins-no-asm = ["compiler_builtins/no-asm"]
compiler-builtins-mangled-names = ["compiler_builtins/mangled-names"]
-
-# Make panics and failed asserts immediately abort without formatting any message
-panic_immediate_abort = ["core/panic_immediate_abort"]
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 08c65a96bc7..6f2ba957bcd 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -14,11 +14,6 @@ use core::ptr::{self, NonNull};
#[doc(inline)]
pub use core::alloc::*;
-#[cfg(not(no_global_oom_handling))]
-use core::any::Any;
-#[cfg(not(no_global_oom_handling))]
-use core::panic::BoxMeUp;
-
#[cfg(test)]
mod tests;
@@ -348,77 +343,14 @@ pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A)
}
}
-/// Payload passed to the panic handler when `handle_alloc_error` is called.
-#[unstable(feature = "panic_oom_payload", issue = "none")]
-#[derive(Debug)]
-pub struct AllocErrorPanicPayload {
- layout: Layout,
-}
-
-impl AllocErrorPanicPayload {
- /// Internal function for the standard library to clone a payload.
- #[unstable(feature = "std_internals", issue = "none")]
- #[doc(hidden)]
- pub fn internal_clone(&self) -> Self {
- AllocErrorPanicPayload { layout: self.layout }
- }
-
- /// Returns the [`Layout`] of the allocation attempt that caused the error.
- #[unstable(feature = "panic_oom_payload", issue = "none")]
- pub fn layout(&self) -> Layout {
- self.layout
- }
-}
-
-#[unstable(feature = "std_internals", issue = "none")]
-#[cfg(not(no_global_oom_handling))]
-unsafe impl BoxMeUp for AllocErrorPanicPayload {
- fn take_box(&mut self) -> *mut (dyn Any + Send) {
- use crate::boxed::Box;
- Box::into_raw(Box::new(self.internal_clone()))
- }
-
- fn get(&mut self) -> &(dyn Any + Send) {
- self
- }
-}
-
// # Allocation error handler
-#[cfg(all(not(no_global_oom_handling), not(test)))]
-fn rust_oom(layout: Layout) -> ! {
- if cfg!(feature = "panic_immediate_abort") {
- core::intrinsics::abort()
- }
-
- extern "Rust" {
- // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
- // that gets resolved to the `#[panic_handler]` function.
- #[lang = "panic_impl"]
- fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> !;
-
- // This symbol is emitted by rustc next to __rust_alloc_error_handler.
- // Its value depends on the -Zoom={panic,abort} compiler option.
- static __rust_alloc_error_handler_should_panic: u8;
- }
-
- // Hack to work around issues with the lifetime of Arguments.
- match format_args!("memory allocation of {} bytes failed", layout.size()) {
- fmt => {
- // Create a PanicInfo with a custom payload for the panic handler.
- let can_unwind = unsafe { __rust_alloc_error_handler_should_panic != 0 };
- let mut pi = core::panic::PanicInfo::internal_constructor(
- Some(&fmt),
- core::panic::Location::caller(),
- can_unwind,
- );
- let payload = AllocErrorPanicPayload { layout };
- pi.set_payload(&payload);
-
- // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
- unsafe { panic_impl(&pi) }
- }
- }
+#[cfg(not(no_global_oom_handling))]
+extern "Rust" {
+ // This is the magic symbol to call the global alloc error handler. rustc generates
+ // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the
+ // default implementations below (`__rdl_oom`) otherwise.
+ fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
}
/// Abort on memory allocation error or failure.
@@ -443,7 +375,9 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {
}
fn rt_error(layout: Layout) -> ! {
- rust_oom(layout);
+ unsafe {
+ __rust_alloc_error_handler(layout.size(), layout.align());
+ }
}
unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 2c6a266e2a1..a002421aeef 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -135,7 +135,6 @@
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_uninit_array_transpose)]
-#![feature(panic_internals)]
#![feature(pattern)]
#![feature(pointer_byte_offsets)]
#![feature(provide_any)]
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 109387b09d0..f2fda64a1ee 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -67,7 +67,7 @@ llvm-libunwind = ["unwind/llvm-libunwind"]
system-llvm-libunwind = ["unwind/system-llvm-libunwind"]
# Make panics and failed asserts immediately abort without formatting any message
-panic_immediate_abort = ["alloc/panic_immediate_abort"]
+panic_immediate_abort = ["core/panic_immediate_abort"]
# Enable std_detect default features for stdarch/crates/std_detect:
# https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 31400aa1820..318a46d1b63 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -320,7 +320,6 @@
#![feature(get_mut_unchecked)]
#![feature(map_try_insert)]
#![feature(new_uninit)]
-#![feature(panic_oom_payload)]
#![feature(slice_concat_trait)]
#![feature(thin_box)]
#![feature(try_reserve_kind)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index ca4cf68ad54..a46a29cbad6 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -245,24 +245,19 @@ fn default_hook(info: &PanicInfo<'_>) {
// The current implementation always returns `Some`.
let location = info.location().unwrap();
+
+ let msg = match info.payload().downcast_ref::<&'static str>() {
+ Some(s) => *s,
+ None => match info.payload().downcast_ref::<String>() {
+ Some(s) => &s[..],
+ None => "Box<dyn Any>",
+ },
+ };
let thread = thread_info::current_thread();
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
let write = |err: &mut dyn crate::io::Write| {
- // Use the panic message directly if available, otherwise take it from
- // the payload.
- if let Some(msg) = info.message() {
- let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
- } else {
- let msg = if let Some(s) = info.payload().downcast_ref::<&'static str>() {
- *s
- } else if let Some(s) = info.payload().downcast_ref::<String>() {
- &s[..]
- } else {
- "Box<dyn Any>"
- };
- let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
- }
+ let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
@@ -529,8 +524,6 @@ pub fn panicking() -> bool {
#[cfg(not(test))]
#[panic_handler]
pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
- use alloc::alloc::AllocErrorPanicPayload;
-
struct PanicPayload<'a> {
inner: &'a fmt::Arguments<'a>,
string: Option<String>,
@@ -557,7 +550,8 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
fn take_box(&mut self) -> *mut (dyn Any + Send) {
// We do two allocations here, unfortunately. But (a) they're required with the current
- // scheme, and (b) OOM uses its own separate payload type which doesn't allocate.
+ // scheme, and (b) we don't handle panic + OOM properly anyway (see comment in
+ // begin_panic below).
let contents = mem::take(self.fill());
Box::into_raw(Box::new(contents))
}
@@ -582,14 +576,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
let loc = info.location().unwrap(); // The current implementation always returns Some
let msg = info.message().unwrap(); // The current implementation always returns Some
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
- if let Some(payload) = info.payload().downcast_ref::<AllocErrorPanicPayload>() {
- rust_panic_with_hook(
- &mut payload.internal_clone(),
- info.message(),
- loc,
- info.can_unwind(),
- );
- } else if let Some(msg) = msg.as_str() {
+ if let Some(msg) = msg.as_str() {
rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind());
} else {
rust_panic_with_hook(
@@ -636,7 +623,11 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> {
fn take_box(&mut self) -> *mut (dyn Any + Send) {
- // 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, but then again we're not
+ // really ready for panic on OOM anyway. If we do start doing this, then we should
+ // propagate this allocation to be performed in the parent of this thread instead of the
+ // thread that's panicking.
let data = match self.inner.take() {
Some(a) => Box::new(a) as Box<dyn Any + Send>,
None => process::abort(),