about summary refs log tree commit diff
path: root/src/libstd/sys/windows
diff options
context:
space:
mode:
authorDiggory Blake <diggsey@googlemail.com>2015-08-26 01:44:55 +0100
committerDiggory Blake <diggsey@googlemail.com>2015-09-04 01:25:15 +0100
commitd4fc3ec208186f0a9de8d05a6802c95b07e058fd (patch)
tree6a5f95c3d8cfb20e65f08b3d67036a966308fffe /src/libstd/sys/windows
parentac12c7f1ed7de4fb564ae637f55199eb553e5126 (diff)
downloadrust-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.rs63
-rw-r--r--src/libstd/sys/windows/printing/gnu.rs22
-rw-r--r--src/libstd/sys/windows/printing/msvc.rs42
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)
+}