about summary refs log tree commit diff
path: root/library/std/src/sys_common
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2023-10-03 23:13:55 +0200
committerjoboet <jonasboettiger@icloud.com>2023-10-03 23:57:37 +0200
commitfd23276ca87b4b56918e4a87737859cfd77d657c (patch)
treefdeeaca44c4aea4278560e6c1eac403f67e2d367 /library/std/src/sys_common
parent36aab8df0ab8a76f1c4f95ce8becefdd8a6fe526 (diff)
std: panic when the global allocator tries to register a TLS destructor
Diffstat (limited to 'library/std/src/sys_common')
-rw-r--r--library/std/src/sys_common/thread_local_dtor.rs14
1 files changed, 9 insertions, 5 deletions
diff --git a/library/std/src/sys_common/thread_local_dtor.rs b/library/std/src/sys_common/thread_local_dtor.rs
index 844946eda03..5d15140a9da 100644
--- a/library/std/src/sys_common/thread_local_dtor.rs
+++ b/library/std/src/sys_common/thread_local_dtor.rs
@@ -13,6 +13,7 @@
 #![unstable(feature = "thread_local_internals", issue = "none")]
 #![allow(dead_code)]
 
+use crate::cell::RefCell;
 use crate::ptr;
 use crate::sys_common::thread_local_key::StaticKey;
 
@@ -28,17 +29,20 @@ pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut
     // flagged for destruction.
 
     static DTORS: StaticKey = StaticKey::new(Some(run_dtors));
-    type List = Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
+    // FIXME(joboet): integrate RefCell into pointer to avoid infinite recursion
+    // when the global allocator tries to register a destructor and just panic
+    // instead.
+    type List = RefCell<Vec<(*mut u8, unsafe extern "C" fn(*mut u8))>>;
     if DTORS.get().is_null() {
-        let v: Box<List> = Box::new(Vec::new());
+        let v: Box<List> = Box::new(RefCell::new(Vec::new()));
         DTORS.set(Box::into_raw(v) as *mut u8);
     }
-    let list: &mut List = &mut *(DTORS.get() as *mut List);
-    list.push((t, dtor));
+    let list = &*(DTORS.get() as *const List);
+    list.try_borrow_mut().expect("global allocator may not use TLS").push((t, dtor));
 
     unsafe extern "C" fn run_dtors(mut ptr: *mut u8) {
         while !ptr.is_null() {
-            let list: Box<List> = Box::from_raw(ptr as *mut List);
+            let list = Box::from_raw(ptr as *mut List).into_inner();
             for (ptr, dtor) in list.into_iter() {
                 dtor(ptr);
             }