Add basic backtrace functionality
Whenever a failure happens, if a program is run with `RUST_LOG=std::rt::backtrace` a backtrace will be printed to the task's stderr handle. Stack traces are uncondtionally printed on double-failure and rtabort!(). This ended up having a nontrivial implementation, and here's some highlights of it: * We're bundling libbacktrace for everything but OSX and Windows * We use libgcc_s and its libunwind apis to get a backtrace of instruction pointers * On OSX we use dladdr() to go from an instruction pointer to a symbol * On unix that isn't OSX, we use libbacktrace to get symbols * Windows, as usual, has an entirely separate implementation Lots more fun details and comments can be found in the source itself. Closes #10128
This commit is contained in:
@@ -12,6 +12,7 @@ use container::Container;
|
||||
use fmt;
|
||||
use from_str::FromStr;
|
||||
use io::IoResult;
|
||||
use io;
|
||||
use iter::Iterator;
|
||||
use libc;
|
||||
use option::{Some, None, Option};
|
||||
@@ -70,20 +71,20 @@ pub fn default_sched_threads() -> uint {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dumb_println(args: &fmt::Arguments) {
|
||||
use io;
|
||||
pub struct Stderr;
|
||||
|
||||
struct Stderr;
|
||||
impl io::Writer for Stderr {
|
||||
fn write(&mut self, data: &[u8]) -> IoResult<()> {
|
||||
unsafe {
|
||||
libc::write(libc::STDERR_FILENO,
|
||||
data.as_ptr() as *libc::c_void,
|
||||
data.len() as libc::size_t);
|
||||
}
|
||||
Ok(()) // yes, we're lying
|
||||
impl io::Writer for Stderr {
|
||||
fn write(&mut self, data: &[u8]) -> IoResult<()> {
|
||||
unsafe {
|
||||
libc::write(libc::STDERR_FILENO,
|
||||
data.as_ptr() as *libc::c_void,
|
||||
data.len() as libc::size_t);
|
||||
}
|
||||
Ok(()) // yes, we're lying
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dumb_println(args: &fmt::Arguments) {
|
||||
let mut w = Stderr;
|
||||
let _ = fmt::writeln(&mut w as &mut io::Writer, args);
|
||||
}
|
||||
@@ -140,6 +141,10 @@ memory and partly incapable of presentation to others.",
|
||||
rterrln!("{}", "");
|
||||
rterrln!("fatal runtime error: {}", msg);
|
||||
|
||||
{
|
||||
let mut err = Stderr;
|
||||
let _err = ::rt::backtrace::write(&mut err);
|
||||
}
|
||||
abort();
|
||||
|
||||
fn abort() -> ! {
|
||||
|
||||
Reference in New Issue
Block a user