Skip to content

Commit 471d830

Browse files
committed
avoid nesting the user-defined main so deeply on the stack
1 parent 9f7fe81 commit 471d830

File tree

5 files changed

+26
-45
lines changed

5 files changed

+26
-45
lines changed

library/std/src/rt.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn lang_start_internal(
157157
argc: isize,
158158
argv: *const *const u8,
159159
sigpipe: u8,
160-
) -> Result<isize, !> {
160+
) -> isize {
161161
// Guard against the code called by this function from unwinding outside of the Rust-controlled
162162
// code, which is UB. This is a requirement imposed by a combination of how the
163163
// `#[lang="start"]` attribute is implemented as well as by the implementation of the panicking
@@ -174,18 +174,24 @@ fn lang_start_internal(
174174
panic::catch_unwind(move || {
175175
// SAFETY: Only called once during runtime initialization.
176176
unsafe { init(argc, argv, sigpipe) };
177-
let ret_code =
178-
panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize).map_err(
179-
move |e| {
180-
// Print a specific error when we abort due to a panicing payload destructor.
181-
mem::forget(e);
182-
rtabort!("drop of the panic payload panicked");
183-
},
184-
);
177+
178+
let ret_code = panic::catch_unwind(main).unwrap_or_else(move |payload| {
179+
// Carefully dispose of the panic payload.
180+
let payload = panic::AssertUnwindSafe(payload);
181+
panic::catch_unwind(move || drop({ payload }.0)).unwrap_or_else(move |e| {
182+
mem::forget(e); // do *not* drop the 2nd payload
183+
rtabort!("drop of the panic payload panicked");
184+
});
185+
// Return error code for panicking programs.
186+
101
187+
});
188+
let ret_code = ret_code as isize;
189+
185190
cleanup();
186191
// Guard against multiple threads calling `libc::exit` concurrently.
187192
// See the documentation for `unique_thread_exit` for more information.
188193
crate::sys::exit_guard::unique_thread_exit();
194+
189195
ret_code
190196
})
191197
.unwrap_or_else(handle_rt_panic)
@@ -199,11 +205,10 @@ fn lang_start<T: crate::process::Termination + 'static>(
199205
argv: *const *const u8,
200206
sigpipe: u8,
201207
) -> isize {
202-
let Ok(v) = lang_start_internal(
208+
lang_start_internal(
203209
&move || crate::sys::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
204210
argc,
205211
argv,
206212
sigpipe,
207-
);
208-
v
213+
)
209214
}

src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr

+3-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,9 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
1515
= 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
1616
= 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
1717
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
18-
= 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
19-
= 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
20-
= 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
21-
= note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC
22-
= 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
23-
= 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
24-
= 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
18+
= note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC
19+
= note: inside `std::panicking::r#try::<isize, {closure@std::rt::lang_start_internal::{closure#0}}>` at RUSTLIB/std/src/panicking.rs:LL:CC
20+
= note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#0}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC
2521
= note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC
2622
= note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC
2723

src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
1010
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
1111
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
1212
RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
13-
RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#0}::{closure#0})
14-
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
15-
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
16-
RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
1713
RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#0})
1814
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
1915
RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)

src/tools/miri/tests/pass/backtrace/backtrace-global-alloc.stderr

+3-11
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,15 @@
1414
at RUSTLIB/std/src/panicking.rs:LL:CC
1515
7: std::panic::catch_unwind
1616
at RUSTLIB/std/src/panic.rs:LL:CC
17-
8: std::rt::lang_start_internal::{closure#0}::{closure#0}
17+
8: std::rt::lang_start_internal::{closure#0}
1818
at RUSTLIB/std/src/rt.rs:LL:CC
1919
9: std::panicking::r#try::do_call
2020
at RUSTLIB/std/src/panicking.rs:LL:CC
2121
10: std::panicking::r#try
2222
at RUSTLIB/std/src/panicking.rs:LL:CC
2323
11: std::panic::catch_unwind
2424
at RUSTLIB/std/src/panic.rs:LL:CC
25-
12: std::rt::lang_start_internal::{closure#0}
25+
12: std::rt::lang_start_internal
2626
at RUSTLIB/std/src/rt.rs:LL:CC
27-
13: std::panicking::r#try::do_call
28-
at RUSTLIB/std/src/panicking.rs:LL:CC
29-
14: std::panicking::r#try
30-
at RUSTLIB/std/src/panicking.rs:LL:CC
31-
15: std::panic::catch_unwind
32-
at RUSTLIB/std/src/panic.rs:LL:CC
33-
16: std::rt::lang_start_internal
34-
at RUSTLIB/std/src/rt.rs:LL:CC
35-
17: std::rt::lang_start
27+
13: std::rt::lang_start
3628
at RUSTLIB/std/src/rt.rs:LL:CC

src/tools/miri/tests/pass/backtrace/backtrace-std.stderr

+3-11
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,15 @@
2222
at RUSTLIB/std/src/panicking.rs:LL:CC
2323
11: std::panic::catch_unwind
2424
at RUSTLIB/std/src/panic.rs:LL:CC
25-
12: std::rt::lang_start_internal::{closure#0}::{closure#0}
25+
12: std::rt::lang_start_internal::{closure#0}
2626
at RUSTLIB/std/src/rt.rs:LL:CC
2727
13: std::panicking::r#try::do_call
2828
at RUSTLIB/std/src/panicking.rs:LL:CC
2929
14: std::panicking::r#try
3030
at RUSTLIB/std/src/panicking.rs:LL:CC
3131
15: std::panic::catch_unwind
3232
at RUSTLIB/std/src/panic.rs:LL:CC
33-
16: std::rt::lang_start_internal::{closure#0}
33+
16: std::rt::lang_start_internal
3434
at RUSTLIB/std/src/rt.rs:LL:CC
35-
17: std::panicking::r#try::do_call
36-
at RUSTLIB/std/src/panicking.rs:LL:CC
37-
18: std::panicking::r#try
38-
at RUSTLIB/std/src/panicking.rs:LL:CC
39-
19: std::panic::catch_unwind
40-
at RUSTLIB/std/src/panic.rs:LL:CC
41-
20: std::rt::lang_start_internal
42-
at RUSTLIB/std/src/rt.rs:LL:CC
43-
21: std::rt::lang_start
35+
17: std::rt::lang_start
4436
at RUSTLIB/std/src/rt.rs:LL:CC

0 commit comments

Comments
 (0)