Update miri to rustc changes
This commit is contained in:
@@ -8,15 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![cfg_attr(target_os = "nacl", allow(dead_code))]
|
||||
|
||||
/// Common code for printing the backtrace in the same way across the different
|
||||
/// supported platforms.
|
||||
|
||||
use env;
|
||||
use io::prelude::*;
|
||||
use io;
|
||||
use libc;
|
||||
use str;
|
||||
use sync::atomic::{self, Ordering};
|
||||
use path::{self, Path};
|
||||
@@ -41,9 +38,9 @@ pub const HEX_WIDTH: usize = 10;
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Frame {
|
||||
/// Exact address of the call that failed.
|
||||
pub exact_position: *const libc::c_void,
|
||||
pub exact_position: *const u8,
|
||||
/// Address of the enclosing function.
|
||||
pub symbol_addr: *const libc::c_void,
|
||||
pub symbol_addr: *const u8,
|
||||
}
|
||||
|
||||
/// Max number of frames to print.
|
||||
@@ -203,8 +200,10 @@ fn output(w: &mut Write, idx: usize, frame: Frame,
|
||||
///
|
||||
/// See also `output`.
|
||||
#[allow(dead_code)]
|
||||
fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int,
|
||||
format: PrintFormat) -> io::Result<()> {
|
||||
fn output_fileline(w: &mut Write,
|
||||
file: &[u8],
|
||||
line: u32,
|
||||
format: PrintFormat) -> io::Result<()> {
|
||||
// prior line: " ##: {:2$} - func"
|
||||
w.write_all(b"")?;
|
||||
match format {
|
||||
@@ -253,8 +252,26 @@ fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int,
|
||||
// Note that this demangler isn't quite as fancy as it could be. We have lots
|
||||
// of other information in our symbols like hashes, version, type information,
|
||||
// etc. Additionally, this doesn't handle glue symbols at all.
|
||||
pub fn demangle(writer: &mut Write, s: &str, format: PrintFormat) -> io::Result<()> {
|
||||
// First validate the symbol. If it doesn't look like anything we're
|
||||
pub fn demangle(writer: &mut Write, mut s: &str, format: PrintFormat) -> io::Result<()> {
|
||||
// During ThinLTO LLVM may import and rename internal symbols, so strip out
|
||||
// those endings first as they're one of the last manglings applied to
|
||||
// symbol names.
|
||||
let llvm = ".llvm.";
|
||||
if let Some(i) = s.find(llvm) {
|
||||
let candidate = &s[i + llvm.len()..];
|
||||
let all_hex = candidate.chars().all(|c| {
|
||||
match c {
|
||||
'A' ... 'F' | '0' ... '9' => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
|
||||
if all_hex {
|
||||
s = &s[..i];
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the symbol. If it doesn't look like anything we're
|
||||
// expecting, we just print it literally. Note that we must handle non-rust
|
||||
// symbols because we could have any function in the backtrace.
|
||||
let mut valid = true;
|
||||
|
||||
@@ -20,13 +20,13 @@ use sys_common::backtrace::Frame;
|
||||
pub fn foreach_symbol_fileline<F>(frame: Frame,
|
||||
mut f: F,
|
||||
_: &BacktraceContext) -> io::Result<bool>
|
||||
where F: FnMut(&[u8], libc::c_int) -> io::Result<()>
|
||||
where F: FnMut(&[u8], u32) -> io::Result<()>
|
||||
{
|
||||
// pcinfo may return an arbitrary number of file:line pairs,
|
||||
// in the order of stack trace (i.e. inlined calls first).
|
||||
// in order to avoid allocation, we stack-allocate a fixed size of entries.
|
||||
const FILELINE_SIZE: usize = 32;
|
||||
let mut fileline_buf = [(ptr::null(), -1); FILELINE_SIZE];
|
||||
let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE];
|
||||
let ret;
|
||||
let fileline_count = {
|
||||
let state = unsafe { init_state() };
|
||||
@@ -136,7 +136,7 @@ extern {
|
||||
// helper callbacks
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type FileLine = (*const libc::c_char, libc::c_int);
|
||||
type FileLine = (*const libc::c_char, u32);
|
||||
|
||||
extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char,
|
||||
_errnum: libc::c_int) {
|
||||
@@ -162,7 +162,7 @@ extern fn pcinfo_cb(data: *mut libc::c_void,
|
||||
// if the buffer is not full, add file:line to the buffer
|
||||
// and adjust the buffer for next possible calls to pcinfo_cb.
|
||||
if !buffer.is_empty() {
|
||||
buffer[0] = (filename, lineno);
|
||||
buffer[0] = (filename, lineno as u32);
|
||||
unsafe { ptr::write(slot, &mut buffer[1..]); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,11 +44,15 @@ pub mod thread_local;
|
||||
pub mod util;
|
||||
pub mod wtf8;
|
||||
|
||||
#[cfg(any(target_os = "redox", target_os = "l4re"))]
|
||||
pub use sys::net;
|
||||
|
||||
#[cfg(not(any(target_os = "redox", target_os = "l4re")))]
|
||||
pub mod net;
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_os = "redox", target_os = "l4re"))] {
|
||||
pub use sys::net;
|
||||
} else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
|
||||
pub use sys::net;
|
||||
} else {
|
||||
pub mod net;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "backtrace")]
|
||||
#[cfg(any(all(unix, not(target_os = "emscripten")),
|
||||
|
||||
@@ -175,10 +175,15 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
||||
},
|
||||
#[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();
|
||||
// If we're running glibc prior to version 2.26, the lookup
|
||||
// failure could be caused by caching a stale /etc/resolv.conf.
|
||||
// We need to call libc::res_init() to clear the cache. But we
|
||||
// shouldn't call it in on any other platform, because other
|
||||
// res_init implementations aren't thread-safe. See
|
||||
// https://github.com/rust-lang/rust/issues/41570 and
|
||||
// https://github.com/rust-lang/rust/issues/43592.
|
||||
use sys::net::res_init_if_glibc_before_2_26;
|
||||
let _ = res_init_if_glibc_before_2_26();
|
||||
Err(e)
|
||||
},
|
||||
// the cfg is needed here to avoid an "unreachable pattern" warning
|
||||
|
||||
@@ -65,6 +65,31 @@ pub struct Guard {
|
||||
/// each lock, but once a lock is poisoned then all future acquisitions will
|
||||
/// return this error.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::{Arc, Mutex};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mutex = Arc::new(Mutex::new(1));
|
||||
///
|
||||
/// // poison the mutex
|
||||
/// let c_mutex = mutex.clone();
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// let mut data = c_mutex.lock().unwrap();
|
||||
/// *data = 2;
|
||||
/// panic!();
|
||||
/// }).join();
|
||||
///
|
||||
/// match mutex.lock() {
|
||||
/// Ok(_) => unreachable!(),
|
||||
/// Err(p_err) => {
|
||||
/// let data = p_err.get_ref();
|
||||
/// println!("recovered: {}", data);
|
||||
/// }
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// [`Mutex`]: ../../std/sync/struct.Mutex.html
|
||||
/// [`RwLock`]: ../../std/sync/struct.RwLock.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@@ -72,10 +97,16 @@ pub struct PoisonError<T> {
|
||||
guard: T,
|
||||
}
|
||||
|
||||
/// An enumeration of possible errors which can occur while calling the
|
||||
/// [`try_lock`] method.
|
||||
/// An enumeration of possible errors associated with a [`TryLockResult`] which
|
||||
/// can occur while trying to aquire a lock, from the [`try_lock`] method on a
|
||||
/// [`Mutex`] or the [`try_read`] and [`try_write`] methods on an [`RwLock`].
|
||||
///
|
||||
/// [`Mutex`]: struct.Mutex.html
|
||||
/// [`RwLock`]: struct.RwLock.html
|
||||
/// [`TryLockResult`]: type.TryLockResult.html
|
||||
/// [`try_lock`]: struct.Mutex.html#method.try_lock
|
||||
/// [`try_read`]: struct.RwLock.html#method.try_read
|
||||
/// [`try_write`]: struct.RwLock.html#method.try_write
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub enum TryLockError<T> {
|
||||
/// The lock could not be acquired because another thread failed while holding
|
||||
@@ -148,6 +179,28 @@ impl<T> PoisonError<T> {
|
||||
|
||||
/// Consumes this error indicating that a lock is poisoned, returning the
|
||||
/// underlying guard to allow access regardless.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashSet;
|
||||
/// use std::sync::{Arc, Mutex};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mutex = Arc::new(Mutex::new(HashSet::new()));
|
||||
///
|
||||
/// // poison the mutex
|
||||
/// let c_mutex = mutex.clone();
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// let mut data = c_mutex.lock().unwrap();
|
||||
/// data.insert(10);
|
||||
/// panic!();
|
||||
/// }).join();
|
||||
///
|
||||
/// let p_err = mutex.lock().unwrap_err();
|
||||
/// let data = p_err.into_inner();
|
||||
/// println!("recovered {} items", data.len());
|
||||
/// ```
|
||||
#[stable(feature = "sync_poison", since = "1.2.0")]
|
||||
pub fn into_inner(self) -> T { self.guard }
|
||||
|
||||
|
||||
@@ -116,11 +116,18 @@ impl<T> Drop for ReentrantMutex<T> {
|
||||
impl<T: fmt::Debug + 'static> fmt::Debug for ReentrantMutex<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.try_lock() {
|
||||
Ok(guard) => write!(f, "ReentrantMutex {{ data: {:?} }}", &*guard),
|
||||
Ok(guard) => f.debug_struct("ReentrantMutex").field("data", &*guard).finish(),
|
||||
Err(TryLockError::Poisoned(err)) => {
|
||||
write!(f, "ReentrantMutex {{ data: Poisoned({:?}) }}", &**err.get_ref())
|
||||
f.debug_struct("ReentrantMutex").field("data", &**err.get_ref()).finish()
|
||||
},
|
||||
Err(TryLockError::WouldBlock) => write!(f, "ReentrantMutex {{ <locked> }}")
|
||||
Err(TryLockError::WouldBlock) => {
|
||||
struct LockedPlaceholder;
|
||||
impl fmt::Debug for LockedPlaceholder {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("<locked>") }
|
||||
}
|
||||
|
||||
f.debug_struct("ReentrantMutex").field("data", &LockedPlaceholder).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use env;
|
||||
use alloc::boxed::FnBox;
|
||||
use libc;
|
||||
use env;
|
||||
use sync::atomic::{self, Ordering};
|
||||
use sys::stack_overflow;
|
||||
use sys::thread as imp;
|
||||
|
||||
pub unsafe fn start_thread(main: *mut libc::c_void) {
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn start_thread(main: *mut u8) {
|
||||
// Next, set up our stack overflow handler which may get triggered if we run
|
||||
// out of stack.
|
||||
let _handler = stack_overflow::Handler::new();
|
||||
|
||||
@@ -262,7 +262,7 @@ pub unsafe fn register_dtor_fallback(t: *mut u8,
|
||||
unsafe extern fn run_dtors(mut ptr: *mut u8) {
|
||||
while !ptr.is_null() {
|
||||
let list: Box<List> = Box::from_raw(ptr as *mut List);
|
||||
for &(ptr, dtor) in list.iter() {
|
||||
for (ptr, dtor) in list.into_iter() {
|
||||
dtor(ptr);
|
||||
}
|
||||
ptr = DTORS.get();
|
||||
|
||||
@@ -35,8 +35,10 @@ use hash::{Hash, Hasher};
|
||||
use iter::FromIterator;
|
||||
use mem;
|
||||
use ops;
|
||||
use rc::Rc;
|
||||
use slice;
|
||||
use str;
|
||||
use sync::Arc;
|
||||
use sys_common::AsInner;
|
||||
|
||||
const UTF8_REPLACEMENT_CHARACTER: &'static str = "\u{FFFD}";
|
||||
@@ -641,6 +643,18 @@ impl Wtf8 {
|
||||
let boxed: Box<[u8]> = Default::default();
|
||||
unsafe { mem::transmute(boxed) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_arc(&self) -> Arc<Wtf8> {
|
||||
let arc: Arc<[u8]> = Arc::from(&self.bytes);
|
||||
unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Wtf8) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_rc(&self) -> Rc<Wtf8> {
|
||||
let rc: Rc<[u8]> = Rc::from(&self.bytes);
|
||||
unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Wtf8) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user