about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-01-11 10:35:00 +0100
committerRalf Jung <post@ralfj.de>2025-01-11 15:50:53 +0100
commit9f7fe81d53b421e946c1b9ab35d43920428deb94 (patch)
treedb061abda447b5a5b74f2901d8d7e80b413a8ab6
parent7e4077d06fc073442c567d58885b47ed2c5121b8 (diff)
use a single large catch_unwind in lang_start
-rw-r--r--library/std/src/rt.rs36
-rw-r--r--src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr10
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr6
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr14
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-std.stderr14
5 files changed, 56 insertions, 24 deletions
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index b2492238bd3..334a57d372e 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -67,7 +67,7 @@ macro_rules! rtunwrap {
     };
 }
 
-fn handle_rt_panic(e: Box<dyn Any + Send>) {
+fn handle_rt_panic<T>(e: Box<dyn Any + Send>) -> T {
     mem::forget(e);
     rtabort!("initialization or cleanup bug");
 }
@@ -168,19 +168,27 @@ fn lang_start_internal(
     // panic is a std implementation bug. A quite likely one too, as there isn't any way to
     // prevent std from accidentally introducing a panic to these functions. Another is from
     // user code from `main` or, more nefariously, as described in e.g. issue #86030.
-    // SAFETY: Only called once during runtime initialization.
-    panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) })
-        .unwrap_or_else(handle_rt_panic);
-    let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
-        .map_err(move |e| {
-            mem::forget(e);
-            rtabort!("drop of the panic payload panicked");
-        });
-    panic::catch_unwind(cleanup).unwrap_or_else(handle_rt_panic);
-    // Guard against multiple threads calling `libc::exit` concurrently.
-    // See the documentation for `unique_thread_exit` for more information.
-    panic::catch_unwind(crate::sys::exit_guard::unique_thread_exit).unwrap_or_else(handle_rt_panic);
-    ret_code
+    //
+    // We use `catch_unwind` with `handle_rt_panic` instead of `abort_unwind` to make the error in
+    // case of a panic a bit nicer.
+    panic::catch_unwind(move || {
+        // SAFETY: Only called once during runtime initialization.
+        unsafe { init(argc, argv, sigpipe) };
+        let ret_code =
+            panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize).map_err(
+                move |e| {
+                    // Print a specific error when we abort due to a panicing payload destructor.
+                    mem::forget(e);
+                    rtabort!("drop of the panic payload panicked");
+                },
+            );
+        cleanup();
+        // Guard against multiple threads calling `libc::exit` concurrently.
+        // See the documentation for `unique_thread_exit` for more information.
+        crate::sys::exit_guard::unique_thread_exit();
+        ret_code
+    })
+    .unwrap_or_else(handle_rt_panic)
 }
 
 #[cfg(not(any(test, doctest)))]
diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
index b416f0eb689..4a0886cf897 100644
--- a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
+++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr
@@ -15,9 +15,13 @@ LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
    = note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC
    = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC
    = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
-   = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#1}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
-   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
+   = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#0}::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#0}::{closure#0}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
+   = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
+   = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, std::result::Result<isize, !>>` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panicking::r#try::<std::result::Result<isize, !>, {closure@std::rt::lang_start_internal::{closure#0}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
+   = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, std::result::Result<isize, !>>` at RUSTLIB/std/src/panic.rs:LL:CC
    = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC
    = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC
 
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
index 48d9649c920..826645ba3df 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
@@ -10,7 +10,11 @@ RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
 RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
-RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#1})
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#0}::{closure#0})
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
+RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#0})
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
 RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
 RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
index 667ee04e624..30643bc6708 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr
@@ -14,7 +14,7 @@
  at RUSTLIB/std/src/panicking.rs:LL:CC
    7: std::panic::catch_unwind
  at RUSTLIB/std/src/panic.rs:LL:CC
-   8: std::rt::lang_start_internal::{closure#1}
+   8: std::rt::lang_start_internal::{closure#0}::{closure#0}
  at RUSTLIB/std/src/rt.rs:LL:CC
    9: std::panicking::r#try::do_call
  at RUSTLIB/std/src/panicking.rs:LL:CC
@@ -22,7 +22,15 @@
  at RUSTLIB/std/src/panicking.rs:LL:CC
   11: std::panic::catch_unwind
  at RUSTLIB/std/src/panic.rs:LL:CC
-  12: std::rt::lang_start_internal
+  12: std::rt::lang_start_internal::{closure#0}
  at RUSTLIB/std/src/rt.rs:LL:CC
-  13: std::rt::lang_start
+  13: std::panicking::r#try::do_call
+ at RUSTLIB/std/src/panicking.rs:LL:CC
+  14: std::panicking::r#try
+ at RUSTLIB/std/src/panicking.rs:LL:CC
+  15: std::panic::catch_unwind
+ at RUSTLIB/std/src/panic.rs:LL:CC
+  16: std::rt::lang_start_internal
+ at RUSTLIB/std/src/rt.rs:LL:CC
+  17: std::rt::lang_start
  at RUSTLIB/std/src/rt.rs:LL:CC
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
index b3a3a9d654a..e04d2e561d7 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-std.stderr
@@ -22,7 +22,7 @@
  at RUSTLIB/std/src/panicking.rs:LL:CC
   11: std::panic::catch_unwind
  at RUSTLIB/std/src/panic.rs:LL:CC
-  12: std::rt::lang_start_internal::{closure#1}
+  12: std::rt::lang_start_internal::{closure#0}::{closure#0}
  at RUSTLIB/std/src/rt.rs:LL:CC
   13: std::panicking::r#try::do_call
  at RUSTLIB/std/src/panicking.rs:LL:CC
@@ -30,7 +30,15 @@
  at RUSTLIB/std/src/panicking.rs:LL:CC
   15: std::panic::catch_unwind
  at RUSTLIB/std/src/panic.rs:LL:CC
-  16: std::rt::lang_start_internal
+  16: std::rt::lang_start_internal::{closure#0}
  at RUSTLIB/std/src/rt.rs:LL:CC
-  17: std::rt::lang_start
+  17: std::panicking::r#try::do_call
+ at RUSTLIB/std/src/panicking.rs:LL:CC
+  18: std::panicking::r#try
+ at RUSTLIB/std/src/panicking.rs:LL:CC
+  19: std::panic::catch_unwind
+ at RUSTLIB/std/src/panic.rs:LL:CC
+  20: std::rt::lang_start_internal
+ at RUSTLIB/std/src/rt.rs:LL:CC
+  21: std::rt::lang_start
  at RUSTLIB/std/src/rt.rs:LL:CC