diff options
| author | bors <bors@rust-lang.org> | 2018-04-04 06:19:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-04 06:19:40 +0000 |
| commit | 5758c2dd14fd29caf7c7bb2123eb6b23443b9233 (patch) | |
| tree | 00119e47d0be6aa30215fd510a06a2fde63dd937 /src/libstd | |
| parent | 20338a52401bda3024fd91010a143913a8dc9a6c (diff) | |
| parent | 7db854b36f9598e44fb4d61428d42d7769233e19 (diff) | |
| download | rust-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')
| -rw-r--r-- | src/libstd/rt.rs | 15 | ||||
| -rw-r--r-- | src/libstd/sys/cloudabi/thread.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/redox/thread.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 48 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/thread.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/windows/thread.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys_common/thread_info.rs | 4 |
7 files changed, 61 insertions, 10 deletions
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index e1392762a59..8f945470b7e 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -73,3 +73,18 @@ fn lang_start<T: ::process::Termination + 'static> { lang_start_internal(&move || main().report(), argc, argv) } + +/// Function used for reverting changes to the main stack before setrlimit(). +/// This is POSIX (non-Linux) specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn deinit_stack_guard() { + ::sys::thread::guard::deinit(); +} + +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = ::sys::thread::guard::init(); + ::sys_common::thread_info::reset_guard(main_guard); +} diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs index 78a3b82546e..a22d9053b69 100644 --- a/src/libstd/sys/cloudabi/thread.rs +++ b/src/libstd/sys/cloudabi/thread.rs @@ -118,6 +118,7 @@ pub mod guard { pub unsafe fn init() -> Option<Guard> { None } + pub unsafe fn deinit() {} } fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index c4719a94c7e..f20350269b7 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -91,4 +91,5 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { None } pub unsafe fn init() -> Option<Guard> { None } + pub unsafe fn deinit() {} } 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", diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 6a066509b49..7345843b975 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -46,4 +46,5 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { None } pub unsafe fn init() -> Option<Guard> { None } + pub unsafe fn deinit() {} } diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 43abfbb1f64..4b3d1b586b5 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -96,4 +96,5 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option<Guard> { None } pub unsafe fn init() -> Option<Guard> { None } + pub unsafe fn deinit() {} } diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs index 6a2b6742367..d75cbded734 100644 --- a/src/libstd/sys_common/thread_info.rs +++ b/src/libstd/sys_common/thread_info.rs @@ -50,3 +50,7 @@ pub fn set(stack_guard: Option<Guard>, thread: Thread) { thread, })); } + +pub fn reset_guard(stack_guard: Option<Guard>) { + THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard); +} |
