|
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