std: make thread::current
available in all thread_local!
destructors · qinheping/verify-rust-std@db56087 (original) (raw)
`@@ -21,9 +21,10 @@ pub use crate::panicking::{begin_panic, panic_count};
`
21
21
`pub use core::panicking::{panic_display, panic_fmt};
`
22
22
``
23
23
`#[rustfmt::skip]
`
``
24
`+
use crate::any::Any;
`
24
25
`use crate::sync::Once;
`
25
``
`-
use crate::sys;
`
26
26
`use crate::thread::{self, Thread};
`
``
27
`+
use crate::{mem, panic, sys};
`
27
28
``
28
29
`// Prints to the "panic output", depending on the platform this may be:
`
29
30
`// - the standard error output
`
`@@ -66,6 +67,11 @@ macro_rules! rtunwrap {
`
66
67
`};
`
67
68
`}
`
68
69
``
``
70
`+
fn handle_rt_panic(e: Box<dyn Any + Send>) {
`
``
71
`+
mem::forget(e);
`
``
72
`+
rtabort!("initialization or cleanup bug");
`
``
73
`+
}
`
``
74
+
69
75
`// One-time runtime initialization.
`
70
76
`` // Runs before main
.
``
71
77
`// SAFETY: must be called only once during runtime initialization.
`
`@@ -101,6 +107,20 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
`
101
107
` thread::set_current(thread);
`
102
108
`}
`
103
109
``
``
110
`+
/// Clean up the thread-local runtime state. This should be run after all other
`
``
111
`+
/// code managed by the Rust runtime, but will not cause UB if that condition is
`
``
112
`+
/// not fulfilled. Also note that this function is not guaranteed to be run, but
`
``
113
`+
/// skipping it will cause leaks and therefore is to be avoided.
`
``
114
`+
pub(crate) fn thread_cleanup() {
`
``
115
`+
// This function is run in situations where unwinding leads to an abort
`
``
116
`` +
// (think extern "C"
functions). Abort here instead so that we can
``
``
117
`+
// print a nice message.
`
``
118
`+
panic::catch_unwind(|| {
`
``
119
`+
crate::thread::drop_current();
`
``
120
`+
})
`
``
121
`+
.unwrap_or_else(handle_rt_panic);
`
``
122
`+
}
`
``
123
+
104
124
`// One-time runtime cleanup.
`
105
125
`` // Runs after main
or at program exit.
``
106
126
`// NOTE: this is not guaranteed to run, for example when the program aborts.
`
`@@ -123,11 +143,6 @@ fn lang_start_internal(
`
123
143
`argv: *const *const u8,
`
124
144
`sigpipe: u8,
`
125
145
`) -> Result<isize, !> {
`
126
``
`-
use crate::{mem, panic};
`
127
``
`-
let rt_abort = move |e| {
`
128
``
`-
mem::forget(e);
`
129
``
`-
rtabort!("initialization or cleanup bug");
`
130
``
`-
};
`
131
146
`// Guard against the code called by this function from unwinding outside of the Rust-controlled
`
132
147
`// code, which is UB. This is a requirement imposed by a combination of how the
`
133
148
`` // #[lang="start"]
attribute is implemented as well as by the implementation of the panicking
``
`@@ -139,16 +154,17 @@ fn lang_start_internal(
`
139
154
`// prevent std from accidentally introducing a panic to these functions. Another is from
`
140
155
`` // user code from main
or, more nefariously, as described in e.g. issue #86030.
``
141
156
`// SAFETY: Only called once during runtime initialization.
`
142
``
`-
panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?;
`
``
157
`+
panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) })
`
``
158
`+
.unwrap_or_else(handle_rt_panic);
`
143
159
`let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
`
144
160
`.map_err(move |e| {
`
145
161
` mem::forget(e);
`
146
162
`rtabort!("drop of the panic payload panicked");
`
147
163
`});
`
148
``
`-
panic::catch_unwind(cleanup).map_err(rt_abort)?;
`
``
164
`+
panic::catch_unwind(cleanup).unwrap_or_else(handle_rt_panic);
`
149
165
`` // Guard against multiple threads calling libc::exit
concurrently.
``
150
166
`` // See the documentation for unique_thread_exit
for more information.
``
151
``
`-
panic::catch_unwind(|| crate::sys::exit_guard::unique_thread_exit()).map_err(rt_abort)?;
`
``
167
`+
panic::catch_unwind(crate::sys::exit_guard::unique_thread_exit).unwrap_or_else(handle_rt_panic);
`
152
168
` ret_code
`
153
169
`}
`
154
170
``