about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-04-15 12:27:05 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-04-27 16:15:36 -0700
commitd98ab4faf869ff0430ad73260b13ef8e473ef212 (patch)
tree22fa7775d0ea81021b825738da48498d02ea4f5d /src/libstd/sys
parent0e154aaad6486fa8bf19b02bc3026ede0ceb91cf (diff)
downloadrust-d98ab4faf869ff0430ad73260b13ef8e473ef212.tar.gz
rust-d98ab4faf869ff0430ad73260b13ef8e473ef212.zip
std: Don't assume thread::current() works on panic
Inspecting the current thread's info may not always work due to the TLS value
having been destroyed (or is actively being destroyed). The code for printing
a panic message assumed, however, that it could acquire the thread's name
through this method.

Instead this commit propagates the `Option` outwards to allow the
`std::panicking` module to handle the case where the current thread isn't
present.

While it solves the immediate issue of #24313, there is still another underlying
issue of panicking destructors in thread locals will abort the process.

Closes #24313
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/common/thread_info.rs11
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs2
2 files changed, 6 insertions, 7 deletions
diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs
index 22cb5943371..ae55bae37aa 100644
--- a/src/libstd/sys/common/thread_info.rs
+++ b/src/libstd/sys/common/thread_info.rs
@@ -25,10 +25,9 @@ struct ThreadInfo {
 thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(None) }
 
 impl ThreadInfo {
-    fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
+    fn with<R, F>(f: F) -> Option<R> where F: FnOnce(&mut ThreadInfo) -> R {
         if THREAD_INFO.state() == LocalKeyState::Destroyed {
-            panic!("Use of std::thread::current() is not possible after \
-                    the thread's local data has been destroyed");
+            return None
         }
 
         THREAD_INFO.with(move |c| {
@@ -38,16 +37,16 @@ impl ThreadInfo {
                     thread: NewThread::new(None),
                 })
             }
-            f(c.borrow_mut().as_mut().unwrap())
+            Some(f(c.borrow_mut().as_mut().unwrap()))
         })
     }
 }
 
-pub fn current_thread() -> Thread {
+pub fn current_thread() -> Option<Thread> {
     ThreadInfo::with(|info| info.thread.clone())
 }
 
-pub fn stack_guard() -> usize {
+pub fn stack_guard() -> Option<usize> {
     ThreadInfo::with(|info| info.stack_guard)
 }
 
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 6887095c53a..2bc280d1274 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -81,7 +81,7 @@ mod imp {
         // We're calling into functions with stack checks
         stack::record_sp_limit(0);
 
-        let guard = thread_info::stack_guard();
+        let guard = thread_info::stack_guard().unwrap_or(0);
         let addr = (*info).si_addr as usize;
 
         if guard == 0 || addr < guard - PAGE_SIZE || addr >= guard {