Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #39718

Closed
wants to merge 11 commits into from
4 changes: 3 additions & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
Version 1.15.1 (2017-02-08)
Version 1.15.1 (2017-02-09)
===========================

* [Fix IntoIter::as_mut_slice's signature][39466]
* [Compile compiler builtins with `-fPIC` on 32-bit platforms][39523]

[39466]: https://github.com/rust-lang/rust/pull/39466
[39523]: https://github.com/rust-lang/rust/pull/39523


Version 1.15.0 (2017-02-02)
Expand Down
15 changes: 14 additions & 1 deletion src/doc/book/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ If you want more information, you can get a backtrace by setting the
```text
$ RUST_BACKTRACE=1 ./diverges
thread 'main' panicked at 'This function never returns!', hello.rs:2
Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
hello::diverges
at ./hello.rs:2
hello::main
at ./hello.rs:6
```

If you want the complete backtrace and filenames:

```text
$ RUST_BACKTRACE=full ./diverges
thread 'main' panicked at 'This function never returns!', hello.rs:2
stack backtrace:
1: 0x7f402773a829 - sys::backtrace::write::h0942de78b6c02817K8r
2: 0x7f402773d7fc - panicking::on_panic::h3f23f9d0b5f4c91bu9w
Expand Down Expand Up @@ -262,7 +275,7 @@ note: Run with `RUST_BACKTRACE=1` for a backtrace.
`RUST_BACKTRACE` also works with Cargo’s `run` command:

```text
$ RUST_BACKTRACE=1 cargo run
$ RUST_BACKTRACE=full cargo run
Running `target/debug/diverges`
thread 'main' panicked at 'This function never returns!', hello.rs:2
stack backtrace:
Expand Down
17 changes: 17 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,23 @@ impl<T> From<T> for Box<T> {
}
}

#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
fn from(slice: &'a [T]) -> Box<[T]> {
let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() };
boxed.copy_from_slice(slice);
boxed
}
}

#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a> From<&'a str> for Box<str> {
fn from(s: &'a str) -> Box<str> {
let boxed: Box<[u8]> = Box::from(s.as_bytes());
unsafe { mem::transmute(boxed) }
}
}

impl Box<Any> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
23 changes: 23 additions & 0 deletions src/liballoc/boxed_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use core::any::Any;
use core::ops::Deref;
use core::result::Result::{Err, Ok};
use core::clone::Clone;
use core::f64;
use core::i64;

use std::boxed::Box;

Expand Down Expand Up @@ -117,3 +119,24 @@ fn raw_trait() {
assert_eq!(19, y.get());
}
}

#[test]
fn f64_slice() {
let slice: &[f64] = &[-1.0, 0.0, 1.0, f64::INFINITY];
let boxed: Box<[f64]> = Box::from(slice);
assert_eq!(&*boxed, slice)
}

#[test]
fn i64_slice() {
let slice: &[i64] = &[i64::MIN, -2, -1, 0, 1, 2, i64::MAX];
let boxed: Box<[i64]> = Box::from(slice);
assert_eq!(&*boxed, slice)
}

#[test]
fn str_slice() {
let s = "Hello, world!";
let boxed: Box<str> = Box::from(s);
assert_eq!(&*boxed, s)
}
9 changes: 6 additions & 3 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,9 @@ impl<T> Vec<T> {

/// Reserves capacity for at least `additional` more elements to be inserted
/// in the given `Vec<T>`. The collection may reserve more space to avoid
/// frequent reallocations.
/// frequent reallocations. After calling `reserve`, capacity will be
/// greater than or equal to `self.len() + additional`. Does nothing if
/// capacity is already sufficient.
///
/// # Panics
///
Expand All @@ -456,8 +458,9 @@ impl<T> Vec<T> {
}

/// Reserves the minimum capacity for exactly `additional` more elements to
/// be inserted in the given `Vec<T>`. Does nothing if the capacity is already
/// sufficient.
/// be inserted in the given `Vec<T>`. After calling `reserve_exact`,
/// capacity will be greater than or equal to `self.len() + additional`.
/// Does nothing if the capacity is already sufficient.
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore capacity can not be relied upon to be precisely
Expand Down
10 changes: 7 additions & 3 deletions src/libstd/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,11 @@ fn default_hook(info: &PanicInfo) {
let log_backtrace = {
let panics = update_panic_count(0);

panics >= 2 || backtrace::log_enabled()
if panics >= 2 {
Some(backtrace::PrintFormat::Full)
} else {
backtrace::log_enabled()
}
};

let file = info.location.file;
Expand All @@ -347,8 +351,8 @@ fn default_hook(info: &PanicInfo) {

static FIRST_PANIC: AtomicBool = AtomicBool::new(true);

if log_backtrace {
let _ = backtrace::write(err);
if let Some(format) = log_backtrace {
let _ = backtrace::print(err, format);
} else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace.");
}
Expand Down
11 changes: 8 additions & 3 deletions src/libstd/sys/redox/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@

use libc;
use io;
use sys_common::backtrace::output;
use sys_common::backtrace::Frame;

pub use sys_common::gnu::libbacktrace::*;
pub struct BacktraceContext;

#[inline(never)]
pub fn write(w: &mut io::Write) -> io::Result<()> {
output(w, 0, 0 as *mut libc::c_void, None)
pub fn unwind_backtrace(frames: &mut [Frame])
-> io::Result<(usize, BacktraceContext)>
{
Ok((0, BacktraceContext))
}
5 changes: 4 additions & 1 deletion src/libstd/sys/unix/backtrace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@
/// to symbols. This is a bit of a hokey implementation as-is, but it works for
/// all unix platforms we support right now, so it at least gets the job done.

pub use self::tracing::write;
pub use self::tracing::unwind_backtrace;
pub use self::printing::{foreach_symbol_fileline, resolve_symname};

// tracing impls:
mod tracing;
Expand All @@ -100,3 +101,5 @@ pub mod gnu {
Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
}
}

pub struct BacktraceContext;
31 changes: 22 additions & 9 deletions src/libstd/sys/unix/backtrace/printing/dladdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
use io;
use io::prelude::*;
use libc;
use sys::backtrace::BacktraceContext;
use sys_common::backtrace::Frame;

pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
_symaddr: *mut libc::c_void) -> io::Result<()> {
use sys_common::backtrace::{output};
pub fn resolve_symname<F>(frame: Frame,
callback: F,
_: &BacktraceContext) -> io::Result<()>
where F: FnOnce(Option<&str>) -> io::Result<()>
{
use intrinsics;
use ffi::CStr;

Expand All @@ -31,11 +35,20 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
}

let mut info: Dl_info = unsafe { intrinsics::init() };
if unsafe { dladdr(addr, &mut info) == 0 } {
output(w, idx,addr, None)
let symname = if unsafe { dladdr(frame.exact_position, &mut info) == 0 } {
None
} else {
output(w, idx, addr, Some(unsafe {
CStr::from_ptr(info.dli_sname).to_bytes()
}))
}
unsafe {
CStr::from_ptr(info.dli_sname).to_str().ok()
}
};
callback(symname)
}

pub fn foreach_symbol_fileline<F>(_symbol_addr: Frame,
mut _f: F
_: &BacktraceContext) -> io::Result<bool>
where F: FnMut(&[u8], libc::c_int) -> io::Result<()>
{
Ok(())
}
7 changes: 4 additions & 3 deletions src/libstd/sys/unix/backtrace/printing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::imp::print;
pub use self::imp::{foreach_symbol_fileline, resolve_symname};

#[cfg(any(target_os = "macos", target_os = "ios",
target_os = "emscripten"))]
Expand All @@ -17,5 +17,6 @@ mod imp;

#[cfg(not(any(target_os = "macos", target_os = "ios",
target_os = "emscripten")))]
#[path = "gnu.rs"]
mod imp;
mod imp {
pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
}
49 changes: 20 additions & 29 deletions src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,26 @@ use io::prelude::*;
use io;
use libc;
use mem;
use sys::mutex::Mutex;
use sys::backtrace::BacktraceContext;
use sys_common::backtrace::Frame;

use super::super::printing::print;

#[inline(never)]
pub fn write(w: &mut Write) -> io::Result<()> {
extern {
fn backtrace(buf: *mut *mut libc::c_void,
sz: libc::c_int) -> libc::c_int;
}

// while it doesn't requires lock for work as everything is
// local, it still displays much nicer backtraces when a
// couple of threads panic simultaneously
static LOCK: Mutex = Mutex::new();
unsafe {
LOCK.lock();

writeln!(w, "stack backtrace:")?;
// 100 lines should be enough
const SIZE: usize = 100;
let mut buf: [*mut libc::c_void; SIZE] = mem::zeroed();
let cnt = backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize;

// skipping the first one as it is write itself
for i in 1..cnt {
print(w, i as isize, buf[i], buf[i])?
}
LOCK.unlock();
#[inline(never)] // if we know this is a function call, we can skip it when
// tracing
pub fn unwind_backtrace(frames: &mut [Frame])
-> io::Result<(usize, BacktraceContext)>
{
const FRAME_LEN = 100;
assert!(FRAME_LEN >= frames);
let mut raw_frames = [0; FRAME_LEN];
let nb_frames = backtrace(frames.as_mut_ptr(),
frames.len() as libc::c_int);
for (from, to) in raw_frames[..nb_frames].iter().zip(frames.iter_mut()) {
*to = Frame {
exact_position: *from,
symbol_addr: *from,
};
}
Ok(())
(nb_frames as usize, BacktraceContext)
}

extern fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int;
Loading