Skip to content

Commit

Permalink
Make the abort display a nicer message
Browse files Browse the repository at this point in the history
Mark `panic_abort` as `no-unwind`.

Co-Authored-By: Christopher Durham <cad97@cad97.com>
Co-Authored-By: Gary Guo <gary@garyguo.net>
  • Loading branch information
3 people committed Sep 26, 2022
1 parent 045d7cb commit 6d7ee4b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
4 changes: 3 additions & 1 deletion library/core/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,9 @@ impl<T> Drop for DropNoUnwindSameAnyTypeId<T> {

impl Drop for AbortOnDrop {
fn drop(&mut self) {
crate::intrinsics::abort();
crate::panicking::panic_abort(Some(&format_args!(
"fatal runtime error: drop of the panic payload panicked"
)))
}
}

Expand Down
24 changes: 24 additions & 0 deletions library/core/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
#[inline(never)]
#[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function
fn panic_no_unwind() -> ! {
// Could this be written in terms of:
// `panic_abort(Some(&format_args!("panic in a function that cannot unwind")))`?
if cfg!(feature = "panic_immediate_abort") {
super::intrinsics::abort()
}
Expand All @@ -109,6 +111,28 @@ fn panic_no_unwind() -> ! {
unsafe { panic_impl(&pi) }
}

/// Aborts the process, but with a properly displayed panic message.
#[cold]
#[rustc_allocator_nounwind]
pub(crate) fn panic_abort<'a>(message: Option<&'a fmt::Arguments<'a>>) -> ! {
if cfg!(feature = "panic_immediate_abort") {
super::intrinsics::abort()
}

// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
// that gets resolved to the `#[panic_handler]` function.
extern "Rust" {
#[lang = "panic_impl"]
fn panic_impl(pi: &PanicInfo<'_>) -> !;
}

// PanicInfo with the `can_unwind` flag set to false forces an abort.
let pi = PanicInfo::internal_constructor(message, Location::caller(), false);

// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
unsafe { panic_impl(&pi) }
}

/// The entry point for panicking with a formatted message.
///
/// This is designed to reduce the amount of code required at the call
Expand Down

0 comments on commit 6d7ee4b

Please sign in to comment.