about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorDiggory Blake <diggsey@googlemail.com>2015-09-04 23:17:16 +0100
committerDiggory Blake <diggsey@googlemail.com>2015-09-05 00:56:53 +0100
commit9a83842849f2aaf055c0bde21006bc8f09589b9f (patch)
tree52e3b09a13f170e015101fdaab5528915a751b54 /src/libstd/sys
parentb4de424e4175eefb4fda6e3ed634acfab3ec0daf (diff)
downloadrust-9a83842849f2aaf055c0bde21006bc8f09589b9f.tar.gz
rust-9a83842849f2aaf055c0bde21006bc8f09589b9f.zip
Add line numbers to MSVC backtrace
Add comments
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/windows/backtrace.rs11
-rw-r--r--src/libstd/sys/windows/printing/msvc.rs24
2 files changed, 31 insertions, 4 deletions
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 35e3c1d4663..9534a107d16 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -60,6 +60,9 @@ extern "system" {
 type SymFromAddrFn =
     extern "system" fn(libc::HANDLE, u64, *mut u64,
                        *mut SYMBOL_INFO) -> libc::BOOL;
+type SymGetLineFromAddr64Fn =
+    extern "system" fn(libc::HANDLE, u64, *mut u32,
+                       *mut IMAGEHLP_LINE64) -> libc::BOOL;
 type SymInitializeFn =
     extern "system" fn(libc::HANDLE, *mut libc::c_void,
                        libc::BOOL) -> libc::BOOL;
@@ -99,6 +102,14 @@ struct SYMBOL_INFO {
     Name: [libc::c_char; MAX_SYM_NAME],
 }
 
+#[repr(C)]
+struct IMAGEHLP_LINE64 {
+    SizeOfStruct: u32,
+    Key: *const libc::c_void,
+    LineNumber: u32,
+    Filename: *const libc::c_char,
+    Address: u64,
+}
 
 #[repr(C)]
 enum ADDRESS_MODE {
diff --git a/src/libstd/sys/windows/printing/msvc.rs b/src/libstd/sys/windows/printing/msvc.rs
index 25cef04ca96..81d19374fea 100644
--- a/src/libstd/sys/windows/printing/msvc.rs
+++ b/src/libstd/sys/windows/printing/msvc.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use sys_common::backtrace::output;
+use sys_common::backtrace::{output, output_fileline};
 use ffi::CStr;
 use dynamic_lib::DynamicLibrary;
-use super::{SymFromAddrFn, SYMBOL_INFO, MAX_SYM_NAME};
+use super::{SymFromAddrFn, SymGetLineFromAddr64Fn, SYMBOL_INFO, MAX_SYM_NAME, IMAGEHLP_LINE64};
 use io;
 use io::prelude::*;
 use intrinsics;
@@ -20,6 +20,7 @@ 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 SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn);
 
     let mut info: SYMBOL_INFO = unsafe { intrinsics::init() };
     info.MaxNameLen = MAX_SYM_NAME as libc::c_ulong;
@@ -29,7 +30,7 @@ pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, proce
     info.SizeOfStruct = 88;
 
     let mut displacement = 0u64;
-    let ret = SymFromAddr(process, addr as u64, &mut displacement, &mut info);
+    let ret = SymFromAddr(process, addr, &mut displacement, &mut info);
 
     let name = if ret == libc::TRUE {
         let ptr = info.Name.as_ptr() as *const libc::c_char;
@@ -38,5 +39,20 @@ pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, proce
         None
     };
 
-    output(w, i, addr as usize as *mut libc::c_void, name)
+    try!(output(w, i, addr as usize as *mut libc::c_void, name));
+
+    // Now find out the filename and line number
+    let mut line: IMAGEHLP_LINE64 = unsafe { intrinsics::init() };
+    line.SizeOfStruct = ::mem::size_of::<IMAGEHLP_LINE64>() as u32;
+
+    let mut displacement = 0u32;
+    let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line);
+    if ret == libc::TRUE {
+        output_fileline(w,
+                        unsafe { CStr::from_ptr(line.Filename).to_bytes() },
+                        line.LineNumber as libc::c_int,
+                        false)
+    } else {
+        Ok(())
+    }
 }