diff options
| author | Diggory Blake <diggsey@googlemail.com> | 2015-08-26 01:44:55 +0100 |
|---|---|---|
| committer | Diggory Blake <diggsey@googlemail.com> | 2015-09-04 01:25:15 +0100 |
| commit | d4fc3ec208186f0a9de8d05a6802c95b07e058fd (patch) | |
| tree | 6a5f95c3d8cfb20e65f08b3d67036a966308fffe /src/libstd/sys/windows | |
| parent | ac12c7f1ed7de4fb564ae637f55199eb553e5126 (diff) | |
| download | rust-d4fc3ec208186f0a9de8d05a6802c95b07e058fd.tar.gz rust-d4fc3ec208186f0a9de8d05a6802c95b07e058fd.zip | |
Add line numbers to windows-gnu backtraces
Fix formatting Remove unused imports Refactor Fix msvc build Fix line lengths Formatting Enable backtrace tests Fix using directive on mac pwd info Work-around buildbot PWD bug, and fix libbacktrace configuration Use alternative to `env -u` which is not supported on bitrig Disable tests on 32-bit windows gnu
Diffstat (limited to 'src/libstd/sys/windows')
| -rw-r--r-- | src/libstd/sys/windows/backtrace.rs | 63 | ||||
| -rw-r--r-- | src/libstd/sys/windows/printing/gnu.rs | 22 | ||||
| -rw-r--r-- | src/libstd/sys/windows/printing/msvc.rs | 42 |
3 files changed, 89 insertions, 38 deletions
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index d36ca709c5c..35e3c1d4663 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -27,17 +27,28 @@ use io::prelude::*; use dynamic_lib::DynamicLibrary; -use ffi::CStr; use intrinsics; use io; use libc; -use mem; use path::Path; use ptr; -use str; use sync::StaticMutex; -use sys_common::backtrace::*; +macro_rules! sym{ ($lib:expr, $e:expr, $t:ident) => (unsafe { + let lib = $lib; + match lib.symbol($e) { + Ok(f) => $crate::mem::transmute::<*mut u8, $t>(f), + Err(..) => return Ok(()) + } +}) } + +#[cfg(target_env = "msvc")] +#[path = "printing/msvc.rs"] +mod printing; + +#[cfg(target_env = "gnu")] +#[path = "printing/gnu.rs"] +mod printing; #[allow(non_snake_case)] extern "system" { @@ -302,23 +313,15 @@ pub fn write(w: &mut Write) -> io::Result<()> { // Open up dbghelp.dll, we don't link to it explicitly because it can't // always be found. Additionally, it's nice having fewer dependencies. let path = Path::new("dbghelp.dll"); - let lib = match DynamicLibrary::open(Some(&path)) { + let dbghelp = match DynamicLibrary::open(Some(&path)) { Ok(lib) => lib, Err(..) => return Ok(()), }; - macro_rules! sym{ ($e:expr, $t:ident) => (unsafe { - match lib.symbol($e) { - Ok(f) => mem::transmute::<*mut u8, $t>(f), - Err(..) => return Ok(()) - } - }) } - // Fetch the symbols necessary from dbghelp.dll - let SymFromAddr = sym!("SymFromAddr", SymFromAddrFn); - let SymInitialize = sym!("SymInitialize", SymInitializeFn); - let SymCleanup = sym!("SymCleanup", SymCleanupFn); - let StackWalk64 = sym!("StackWalk64", StackWalk64Fn); + let SymInitialize = sym!(&dbghelp, "SymInitialize", SymInitializeFn); + let SymCleanup = sym!(&dbghelp, "SymCleanup", SymCleanupFn); + let StackWalk64 = sym!(&dbghelp, "StackWalk64", StackWalk64Fn); // Allocate necessary structures for doing the stack walk let process = unsafe { GetCurrentProcess() }; @@ -334,7 +337,9 @@ pub fn write(w: &mut Write) -> io::Result<()> { let _c = Cleanup { handle: process, SymCleanup: SymCleanup }; // And now that we're done with all the setup, do the stack walking! - let mut i = 0; + // Start from -1 to avoid printing this stack frame, which will + // always be exactly the same. + let mut i = -1; try!(write!(w, "stack backtrace:\n")); while StackWalk64(image, process, thread, &mut frame, &mut context, ptr::null_mut(), @@ -346,28 +351,10 @@ pub fn write(w: &mut Write) -> io::Result<()> { frame.AddrReturn.Offset == 0 { break } i += 1; - try!(write!(w, " {:2}: {:#2$x}", i, addr, HEX_WIDTH)); - let mut info: SYMBOL_INFO = unsafe { intrinsics::init() }; - info.MaxNameLen = MAX_SYM_NAME as libc::c_ulong; - // the struct size in C. the value is different to - // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81) - // due to struct alignment. - info.SizeOfStruct = 88; - - let mut displacement = 0u64; - let ret = SymFromAddr(process, addr as u64, &mut displacement, - &mut info); - - if ret == libc::TRUE { - try!(write!(w, " - ")); - let ptr = info.Name.as_ptr() as *const libc::c_char; - let bytes = unsafe { CStr::from_ptr(ptr).to_bytes() }; - match str::from_utf8(bytes) { - Ok(s) => try!(demangle(w, s)), - Err(..) => try!(w.write_all(&bytes[..bytes.len()-1])), - } + + if i >= 0 { + try!(printing::print(w, i, addr-1, &dbghelp, process)); } - try!(w.write_all(&['\n' as u8])); } Ok(()) diff --git a/src/libstd/sys/windows/printing/gnu.rs b/src/libstd/sys/windows/printing/gnu.rs new file mode 100644 index 00000000000..8d3c93bb7b1 --- /dev/null +++ b/src/libstd/sys/windows/printing/gnu.rs @@ -0,0 +1,22 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use dynamic_lib::DynamicLibrary; +use io; +use io::prelude::*; +use libc; + +use sys_common::gnu::libbacktrace; + +pub fn print(w: &mut Write, i: isize, addr: u64, _: &DynamicLibrary, _: libc::HANDLE) + -> io::Result<()> { + let addr = addr as usize as *mut libc::c_void; + libbacktrace::print(w, i, addr, addr) +} diff --git a/src/libstd/sys/windows/printing/msvc.rs b/src/libstd/sys/windows/printing/msvc.rs new file mode 100644 index 00000000000..25cef04ca96 --- /dev/null +++ b/src/libstd/sys/windows/printing/msvc.rs @@ -0,0 +1,42 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use sys_common::backtrace::output; +use ffi::CStr; +use dynamic_lib::DynamicLibrary; +use super::{SymFromAddrFn, SYMBOL_INFO, MAX_SYM_NAME}; +use io; +use io::prelude::*; +use intrinsics; +use libc; + +pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, process: libc::HANDLE) + -> io::Result<()> { + let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn); + + let mut info: SYMBOL_INFO = unsafe { intrinsics::init() }; + info.MaxNameLen = MAX_SYM_NAME as libc::c_ulong; + // the struct size in C. the value is different to + // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81) + // due to struct alignment. + info.SizeOfStruct = 88; + + let mut displacement = 0u64; + let ret = SymFromAddr(process, addr as u64, &mut displacement, &mut info); + + let name = if ret == libc::TRUE { + let ptr = info.Name.as_ptr() as *const libc::c_char; + Some(unsafe { CStr::from_ptr(ptr).to_bytes() }) + } else { + None + }; + + output(w, i, addr as usize as *mut libc::c_void, name) +} |
