Skip to content

Commit 0a47b78

Browse files
committed
std: use catch_unwind instead of drop guard in run_dtors
1 parent c9b39ca commit 0a47b78

File tree

1 file changed

+24
-30
lines changed

1 file changed

+24
-30
lines changed

library/std/src/sys/common/thread_local/fast_local.rs

+24-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use super::lazy::LazyKeyInner;
22
use crate::cell::{Cell, RefCell};
3-
use crate::fmt;
4-
use crate::mem::{self, forget};
3+
use crate::{fmt, mem, panic};
54

65
#[doc(hidden)]
76
#[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
@@ -262,37 +261,32 @@ unsafe fn register_dtor(t: *mut u8, dtor: unsafe fn(*mut u8)) {
262261
/// May only be called on thread exit. In particular, no thread locals may
263262
/// currently be referenced.
264263
pub unsafe extern "C" fn run_dtors(_unused: *mut u8) {
265-
struct Guard;
266-
impl Drop for Guard {
267-
fn drop(&mut self) {
268-
rtabort!("thread local panicked on drop");
269-
}
270-
}
264+
// This function must not unwind. This is ensured by the `extern "C"` ABI,
265+
// but by catching the unwind, we can print a more helpful message.
271266

272-
// This function must not unwind. This is ensured by the `extern "C"` ABI
273-
// regardless, but by using a guard that aborts on drop, we can give a
274-
// nicer abort reason.
275-
let guard = Guard;
276-
let dtors = &DTORS;
267+
match panic::catch_unwind(|| {
268+
let dtors = &DTORS;
277269

278-
loop {
279-
// Ensure that the `RefMut` guard is not held while the destructor is
280-
// executed to allow initializing TLS variables in destructors.
281-
let (t, dtor) = {
282-
let mut dtors = dtors.borrow_mut();
283-
match dtors.pop() {
284-
Some(entry) => entry,
285-
None => break,
286-
}
287-
};
270+
loop {
271+
// Ensure that the `RefMut` guard is not held while the destructor is
272+
// executed to allow initializing TLS variables in destructors.
273+
let (t, dtor) = {
274+
let mut dtors = dtors.borrow_mut();
275+
match dtors.pop() {
276+
Some(entry) => entry,
277+
None => break,
278+
}
279+
};
288280

289-
unsafe {
290-
(dtor)(t);
281+
unsafe {
282+
(dtor)(t);
283+
}
291284
}
292-
}
293285

294-
// All destructors were run, deallocate the list.
295-
drop(dtors.replace(Vec::new()));
296-
// Disarm the guard.
297-
forget(guard);
286+
// All destructors were run, deallocate the list.
287+
drop(dtors.replace(Vec::new()));
288+
}) {
289+
Ok(()) => {}
290+
Err(_) => rtabort!("thread local panicked on drop"),
291+
}
298292
}

0 commit comments

Comments
 (0)