about summary refs log tree commit diff
path: root/src/libstd/sys_common
diff options
context:
space:
mode:
authorDjzin <djzin@users.noreply.github.com>2017-05-27 14:31:47 +0100
committerDjzin <djzin@users.noreply.github.com>2017-05-27 14:31:47 +0100
commit74751358e625878306aa193fed788e79aa53d4fa (patch)
tree1ba9b336d1ddb45d9f688d69f5bd4ede028db622 /src/libstd/sys_common
parentc6307a2fa55c3d62c06b85b349257a8194093442 (diff)
parent3e7908f616745573a11ad7dfad245f12be0069da (diff)
downloadrust-74751358e625878306aa193fed788e79aa53d4fa.tar.gz
rust-74751358e625878306aa193fed788e79aa53d4fa.zip
Merge remote-tracking branch 'upstream/master' into fast-swap
Diffstat (limited to 'src/libstd/sys_common')
-rw-r--r--src/libstd/sys_common/backtrace.rs90
-rw-r--r--src/libstd/sys_common/net.rs23
-rw-r--r--src/libstd/sys_common/poison.rs4
-rw-r--r--src/libstd/sys_common/thread_info.rs7
-rw-r--r--src/libstd/sys_common/thread_local.rs37
-rw-r--r--src/libstd/sys_common/wtf8.rs7
6 files changed, 76 insertions, 92 deletions
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 99297b781e4..617218fe7a5 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -19,7 +19,7 @@ use io;
 use libc;
 use str;
 use sync::atomic::{self, Ordering};
-use path::Path;
+use path::{self, Path};
 use sys::mutex::Mutex;
 use ptr;
 
@@ -93,6 +93,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
     Ok(())
 }
 
+/// Returns a number of frames to remove at the beginning and at the end of the
+/// backtrace, according to the backtrace format.
 fn filter_frames(frames: &[Frame],
                  format: PrintFormat,
                  context: &BacktraceContext) -> (usize, usize)
@@ -101,74 +103,23 @@ fn filter_frames(frames: &[Frame],
         return (0, 0);
     }
 
-    // We want to filter out frames with some prefixes
-    // from both top and bottom of the call stack.
-    static BAD_PREFIXES_TOP: &'static [&'static str] = &[
-        "_ZN3std3sys3imp9backtrace",
-        "ZN3std3sys3imp9backtrace",
-        "std::sys::imp::backtrace",
-        "_ZN3std10sys_common9backtrace",
-        "ZN3std10sys_common9backtrace",
-        "std::sys_common::backtrace",
-        "_ZN3std9panicking",
-        "ZN3std9panicking",
-        "std::panicking",
-        "_ZN4core9panicking",
-        "ZN4core9panicking",
-        "core::panicking",
-        "_ZN4core6result13unwrap_failed",
-        "ZN4core6result13unwrap_failed",
-        "core::result::unwrap_failed",
-        "rust_begin_unwind",
-        "_ZN4drop",
-        "mingw_set_invalid_parameter_handler",
-    ];
-    static BAD_PREFIXES_BOTTOM: &'static [&'static str] = &[
-        "_ZN3std9panicking",
-        "ZN3std9panicking",
-        "std::panicking",
-        "_ZN3std5panic",
-        "ZN3std5panic",
-        "std::panic",
-        "_ZN4core9panicking",
-        "ZN4core9panicking",
-        "core::panicking",
-        "_ZN3std2rt10lang_start",
-        "ZN3std2rt10lang_start",
-        "std::rt::lang_start",
-        "panic_unwind::__rust_maybe_catch_panic",
-        "__rust_maybe_catch_panic",
-        "_rust_maybe_catch_panic",
-        "__libc_start_main",
-        "__rust_try",
-        "_start",
-        "main",
-        "BaseThreadInitThunk",
-        "RtlInitializeExceptionChain",
-        "__scrt_common_main_seh",
-        "_ZN4drop",
-        "mingw_set_invalid_parameter_handler",
-    ];
-
-    let is_good_frame = |frame: Frame, bad_prefixes: &[&str]| {
-        resolve_symname(frame, |symname| {
+    let skipped_before = 0;
+
+    let skipped_after = frames.len() - frames.iter().position(|frame| {
+        let mut is_marker = false;
+        let _ = resolve_symname(*frame, |symname| {
             if let Some(mangled_symbol_name) = symname {
-                if !bad_prefixes.iter().any(|s| mangled_symbol_name.starts_with(s)) {
-                    return Ok(())
+                // Use grep to find the concerned functions
+                if mangled_symbol_name.contains("__rust_begin_short_backtrace") {
+                    is_marker = true;
                 }
             }
-            Err(io::Error::from(io::ErrorKind::Other))
-        }, context).is_ok()
-    };
-
-    let skipped_before = frames.iter().position(|frame| {
-        is_good_frame(*frame, BAD_PREFIXES_TOP)
+            Ok(())
+        }, context);
+        is_marker
     }).unwrap_or(frames.len());
-    let skipped_after = frames[skipped_before..].iter().rev().position(|frame| {
-        is_good_frame(*frame, BAD_PREFIXES_BOTTOM)
-    }).unwrap_or(frames.len() - skipped_before);
 
-    if skipped_before + skipped_after == frames.len() {
+    if skipped_before + skipped_after >= frames.len() {
         // Avoid showing completely empty backtraces
         return (0, 0);
     }
@@ -176,6 +127,15 @@ fn filter_frames(frames: &[Frame],
     (skipped_before, skipped_after)
 }
 
+
+/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
+#[inline(never)]
+pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
+    where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+{
+    f()
+}
+
 /// Controls how the backtrace should be formated.
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
 pub enum PrintFormat {
@@ -262,7 +222,7 @@ fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int,
         if let Ok(cwd) = env::current_dir() {
             if let Ok(stripped) = file_path.strip_prefix(&cwd) {
                 if let Some(s) = stripped.to_str() {
-                    write!(w, "  at ./{}:{}", s, line)?;
+                    write!(w, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
                     already_printed = true;
                 }
             }
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index 3cdeb511945..a1897c8bd67 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -177,9 +177,22 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     };
     let mut res = ptr::null_mut();
     unsafe {
-        cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints,
-                               &mut res))?;
-        Ok(LookupHost { original: res, cur: res })
+        match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) {
+            Ok(_) => {
+                Ok(LookupHost { original: res, cur: res })
+            },
+            #[cfg(unix)]
+            Err(e) => {
+                // The lookup failure could be caused by using a stale /etc/resolv.conf.
+                // See https://github.com/rust-lang/rust/issues/41570.
+                // We therefore force a reload of the nameserver information.
+                c::res_init();
+                Err(e)
+            },
+            // the cfg is needed here to avoid an "unreachable pattern" warning
+            #[cfg(not(unix))]
+            Err(e) => Err(e),
+        }
     }
 }
 
@@ -339,7 +352,7 @@ impl TcpListener {
 
         // Bind our new socket
         let (addrp, len) = addr.into_inner();
-        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
+        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
 
         // Start listening
         cvt(unsafe { c::listen(*sock.as_inner(), 128) })?;
@@ -430,7 +443,7 @@ impl UdpSocket {
 
         let sock = Socket::new(addr, c::SOCK_DGRAM)?;
         let (addrp, len) = addr.into_inner();
-        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
+        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
         Ok(UdpSocket { inner: sock })
     }
 
diff --git a/src/libstd/sys_common/poison.rs b/src/libstd/sys_common/poison.rs
index d9d13240fcc..0127a9eb759 100644
--- a/src/libstd/sys_common/poison.rs
+++ b/src/libstd/sys_common/poison.rs
@@ -73,7 +73,9 @@ pub struct PoisonError<T> {
 }
 
 /// An enumeration of possible errors which can occur while calling the
-/// `try_lock` method.
+/// [`try_lock`] method.
+///
+/// [`try_lock`]: struct.Mutex.html#method.try_lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum TryLockError<T> {
     /// The lock could not be acquired because another thread failed while holding
diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs
index 95d8b6cc951..5ed48ee4558 100644
--- a/src/libstd/sys_common/thread_info.rs
+++ b/src/libstd/sys_common/thread_info.rs
@@ -31,7 +31,7 @@ impl ThreadInfo {
             if c.borrow().is_none() {
                 *c.borrow_mut() = Some(ThreadInfo {
                     stack_guard: None,
-                    thread: NewThread::new(None),
+                    thread: Thread::new(None),
                 })
             }
             Some(f(c.borrow_mut().as_mut().unwrap()))
@@ -54,8 +54,3 @@ pub fn set(stack_guard: Option<usize>, thread: Thread) {
         thread: thread,
     }));
 }
-
-// a hack to get around privacy restrictions; implemented by `std::thread`
-pub trait NewThread {
-    fn new(name: Option<String>) -> Self;
-}
diff --git a/src/libstd/sys_common/thread_local.rs b/src/libstd/sys_common/thread_local.rs
index 25a9d5720d9..0ade90e64c3 100644
--- a/src/libstd/sys_common/thread_local.rs
+++ b/src/libstd/sys_common/thread_local.rs
@@ -61,6 +61,7 @@
 use sync::atomic::{self, AtomicUsize, Ordering};
 
 use sys::thread_local as imp;
+use sys_common::mutex::Mutex;
 
 /// A type for TLS keys that are statically allocated.
 ///
@@ -145,20 +146,6 @@ impl StaticKey {
     #[inline]
     pub unsafe fn set(&self, val: *mut u8) { imp::set(self.key(), val) }
 
-    /// Deallocates this OS TLS key.
-    ///
-    /// This function is unsafe as there is no guarantee that the key is not
-    /// currently in use by other threads or will not ever be used again.
-    ///
-    /// Note that this does *not* run the user-provided destructor if one was
-    /// specified at definition time. Doing so must be done manually.
-    pub unsafe fn destroy(&self) {
-        match self.key.swap(0, Ordering::SeqCst) {
-            0 => {}
-            n => { imp::destroy(n as imp::Key) }
-        }
-    }
-
     #[inline]
     unsafe fn key(&self) -> imp::Key {
         match self.key.load(Ordering::Relaxed) {
@@ -168,6 +155,24 @@ impl StaticKey {
     }
 
     unsafe fn lazy_init(&self) -> usize {
+        // Currently the Windows implementation of TLS is pretty hairy, and
+        // it greatly simplifies creation if we just synchronize everything.
+        //
+        // Additionally a 0-index of a tls key hasn't been seen on windows, so
+        // we just simplify the whole branch.
+        if imp::requires_synchronized_create() {
+            static INIT_LOCK: Mutex = Mutex::new();
+            INIT_LOCK.lock();
+            let mut key = self.key.load(Ordering::SeqCst);
+            if key == 0 {
+                key = imp::create(self.dtor) as usize;
+                self.key.store(key, Ordering::SeqCst);
+            }
+            INIT_LOCK.unlock();
+            assert!(key != 0);
+            return key
+        }
+
         // POSIX allows the key created here to be 0, but the compare_and_swap
         // below relies on using 0 as a sentinel value to check who won the
         // race to set the shared TLS key. As far as I know, there is no
@@ -227,7 +232,9 @@ impl Key {
 
 impl Drop for Key {
     fn drop(&mut self) {
-        unsafe { imp::destroy(self.key) }
+        // Right now Windows doesn't support TLS key destruction, but this also
+        // isn't used anywhere other than tests, so just leak the TLS key.
+        // unsafe { imp::destroy(self.key) }
     }
 }
 
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index b486d4ffda3..df5e4ef1d88 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -351,6 +351,12 @@ impl Wtf8Buf {
     pub fn into_box(self) -> Box<Wtf8> {
         unsafe { mem::transmute(self.bytes.into_boxed_slice()) }
     }
+
+    /// Converts a `Box<Wtf8>` into a `Wtf8Buf`.
+    pub fn from_box(boxed: Box<Wtf8>) -> Wtf8Buf {
+        let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Wtf8Buf { bytes: bytes.into_vec() }
+    }
 }
 
 /// Create a new WTF-8 string from an iterator of code points.
@@ -744,6 +750,7 @@ impl<'a> Iterator for Wtf8CodePoints<'a> {
     }
 }
 
+/// Generates a wide character sequence for potentially ill-formed UTF-16.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct EncodeWide<'a> {