@@ -245,24 +245,19 @@ fn default_hook(info: &PanicInfo<'_>) {
245
245
246
246
// The current implementation always returns `Some`.
247
247
let location = info.location().unwrap();
248
+
249
+ let msg = match info.payload().downcast_ref::<&'static str>() {
250
+ Some(s) => *s,
251
+ None => match info.payload().downcast_ref::<String>() {
252
+ Some(s) => &s[..],
253
+ None => "Box<dyn Any>",
254
+ },
255
+ };
248
256
let thread = thread_info::current_thread();
249
257
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
250
258
251
259
let write = |err: &mut dyn crate::io::Write| {
252
- // Use the panic message directly if available, otherwise take it from
253
- // the payload.
254
- if let Some(msg) = info.message() {
255
- let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
256
- } else {
257
- let msg = if let Some(s) = info.payload().downcast_ref::<&'static str>() {
258
- *s
259
- } else if let Some(s) = info.payload().downcast_ref::<String>() {
260
- &s[..]
261
- } else {
262
- "Box<dyn Any>"
263
- };
264
- let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
265
- }
260
+ let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}");
266
261
267
262
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
268
263
@@ -529,8 +524,6 @@ pub fn panicking() -> bool {
529
524
#[cfg(not(test))]
530
525
#[panic_handler]
531
526
pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
532
- use alloc::alloc::AllocErrorPanicPayload;
533
-
534
527
struct PanicPayload<'a> {
535
528
inner: &'a fmt::Arguments<'a>,
536
529
string: Option<String>,
@@ -557,7 +550,8 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
557
550
unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
558
551
fn take_box(&mut self) -> *mut (dyn Any + Send) {
559
552
// We do two allocations here, unfortunately. But (a) they're required with the current
560
- // scheme, and (b) OOM uses its own separate payload type which doesn't allocate.
553
+ // scheme, and (b) we don't handle panic + OOM properly anyway (see comment in
554
+ // begin_panic below).
561
555
let contents = mem::take(self.fill());
562
556
Box::into_raw(Box::new(contents))
563
557
}
@@ -582,14 +576,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
582
576
let loc = info.location().unwrap(); // The current implementation always returns Some
583
577
let msg = info.message().unwrap(); // The current implementation always returns Some
584
578
crate::sys_common::backtrace::__rust_end_short_backtrace(move || {
585
- if let Some(payload) = info.payload().downcast_ref::<AllocErrorPanicPayload>() {
586
- rust_panic_with_hook(
587
- &mut payload.internal_clone(),
588
- info.message(),
589
- loc,
590
- info.can_unwind(),
591
- );
592
- } else if let Some(msg) = msg.as_str() {
579
+ if let Some(msg) = msg.as_str() {
593
580
rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind());
594
581
} else {
595
582
rust_panic_with_hook(
@@ -636,7 +623,11 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
636
623
637
624
unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> {
638
625
fn take_box(&mut self) -> *mut (dyn Any + Send) {
639
- // Note that this should be the only allocation performed in this code path.
626
+ // Note that this should be the only allocation performed in this code path. Currently
627
+ // this means that panic!() on OOM will invoke this code path, but then again we're not
628
+ // really ready for panic on OOM anyway. If we do start doing this, then we should
629
+ // propagate this allocation to be performed in the parent of this thread instead of the
630
+ // thread that's panicking.
640
631
let data = match self.inner.take() {
641
632
Some(a) => Box::new(a) as Box<dyn Any + Send>,
642
633
None => process::abort(),
0 commit comments