about summary refs log tree commit diff
path: root/src/libstd/sys/unix
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-04 06:19:40 +0000
committerbors <bors@rust-lang.org>2018-04-04 06:19:40 +0000
commit5758c2dd14fd29caf7c7bb2123eb6b23443b9233 (patch)
tree00119e47d0be6aa30215fd510a06a2fde63dd937 /src/libstd/sys/unix
parent20338a52401bda3024fd91010a143913a8dc9a6c (diff)
parent7db854b36f9598e44fb4d61428d42d7769233e19 (diff)
downloadrust-5758c2dd14fd29caf7c7bb2123eb6b23443b9233.tar.gz
rust-5758c2dd14fd29caf7c7bb2123eb6b23443b9233.zip
Auto merge of #48575 - ishitatsuyuki:unix-no-thread, r=alexcrichton
rustc_driver: get rid of the extra thread

**Do not rollup**

We can alter the stack size afterwards on Unix.

Having a separate thread causes poor debugging experience when interrupting with signals. I have to get the backtrace of the all thread, as the main thread is waiting to join doing nothing else. This patch allows me to just run `bt` to get the desired backtrace.
Diffstat (limited to 'src/libstd/sys/unix')
-rw-r--r--src/libstd/sys/unix/thread.rs48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 72cdb9440b8..2db3d4a5744 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -209,6 +209,7 @@ pub mod guard {
     pub type Guard = Range<usize>;
     pub unsafe fn current() -> Option<Guard> { None }
     pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
 }
 
 
@@ -222,8 +223,8 @@ pub mod guard {
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
     use libc;
-    use libc::mmap;
-    use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
+    use libc::{mmap, mprotect};
+    use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
     use ops::Range;
     use sys::os;
 
@@ -284,10 +285,10 @@ pub mod guard {
         ret
     }
 
-    pub unsafe fn init() -> Option<Guard> {
-        PAGE_SIZE = os::page_size();
-
-        let mut stackaddr = get_stack_start()?;
+    // Precondition: PAGE_SIZE is initialized.
+    unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> {
+        assert!(PAGE_SIZE != 0);
+        let stackaddr = get_stack_start()?;
 
         // Ensure stackaddr is page aligned! A parent process might
         // have reset RLIMIT_STACK to be non-page aligned. The
@@ -296,10 +297,17 @@ pub mod guard {
         // page-aligned, calculate the fix such that stackaddr <
         // new_page_aligned_stackaddr < stackaddr + stacksize
         let remainder = (stackaddr as usize) % PAGE_SIZE;
-        if remainder != 0 {
-            stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder)
-                as *mut libc::c_void;
-        }
+        Some(if remainder == 0 {
+            stackaddr
+        } else {
+            ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void
+        })
+    }
+
+    pub unsafe fn init() -> Option<Guard> {
+        PAGE_SIZE = os::page_size();
+
+        let stackaddr = get_stack_start_aligned()?;
 
         if cfg!(target_os = "linux") {
             // Linux doesn't allocate the whole stack right away, and
@@ -336,6 +344,26 @@ pub mod guard {
         }
     }
 
+    pub unsafe fn deinit() {
+        if !cfg!(target_os = "linux") {
+            if let Some(stackaddr) = get_stack_start_aligned() {
+                // Remove the protection on the guard page.
+                // FIXME: we cannot unmap the page, because when we mmap()
+                // above it may be already mapped by the OS, which we can't
+                // detect from mmap()'s return value. If we unmap this page,
+                // it will lead to failure growing stack size on platforms like
+                // macOS. Instead, just restore the page to a writable state.
+                // This ain't Linux, so we probably don't need to care about
+                // execstack.
+                let result = mprotect(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE);
+
+                if result != 0 {
+                    panic!("unable to reset the guard page");
+                }
+            }
+        }
+    }
+
     #[cfg(any(target_os = "macos",
               target_os = "bitrig",
               target_os = "openbsd",