Skip to content
Closed
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