|
1 | 1 | use super::lazy::LazyKeyInner;
|
2 | 2 | use crate::cell::{Cell, RefCell};
|
3 |
| -use crate::fmt; |
4 |
| -use crate::mem::{self, forget}; |
| 3 | +use crate::{fmt, mem, panic}; |
5 | 4 |
|
6 | 5 | #[doc(hidden)]
|
7 | 6 | #[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)) {
|
262 | 261 | /// May only be called on thread exit. In particular, no thread locals may
|
263 | 262 | /// currently be referenced.
|
264 | 263 | 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. |
271 | 266 |
|
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; |
277 | 269 |
|
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 | + }; |
288 | 280 |
|
289 |
| - unsafe { |
290 |
| - (dtor)(t); |
| 281 | + unsafe { |
| 282 | + (dtor)(t); |
| 283 | + } |
291 | 284 | }
|
292 |
| - } |
293 | 285 |
|
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 | + } |
298 | 292 | }
|
0 commit comments