about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-01-26 12:18:00 +0000
committerbors <bors@rust-lang.org>2018-01-26 12:18:00 +0000
commita97cd17f5d71fb4ec362f4fbd79373a6e7ed7b82 (patch)
treea36cec3088f2a98cdec77debdac9e4e807a29772 /src/libstd
parent566905030380151f90708fa340312c9ca2c6056c (diff)
parent634f8cc06a88eb978c5e52390014740c4bab1e33 (diff)
downloadrust-a97cd17f5d71fb4ec362f4fbd79373a6e7ed7b82.tar.gz
rust-a97cd17f5d71fb4ec362f4fbd79373a6e7ed7b82.zip
Auto merge of #47252 - Zoxc:backtrace-win, r=alexcrichton
Print inlined functions on Windows

Split from https://github.com/rust-lang/rust/pull/45637

r? @alexcrichton
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sys/cloudabi/backtrace.rs1
-rw-r--r--src/libstd/sys/redox/backtrace/tracing.rs1
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs1
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/gcc_s.rs1
-rw-r--r--src/libstd/sys/windows/backtrace/mod.rs31
-rw-r--r--src/libstd/sys/windows/backtrace/printing/msvc.rs54
-rw-r--r--src/libstd/sys/windows/c.rs4
-rw-r--r--src/libstd/sys_common/backtrace.rs3
8 files changed, 59 insertions, 37 deletions
diff --git a/src/libstd/sys/cloudabi/backtrace.rs b/src/libstd/sys/cloudabi/backtrace.rs
index 33d93179237..1b970187558 100644
--- a/src/libstd/sys/cloudabi/backtrace.rs
+++ b/src/libstd/sys/cloudabi/backtrace.rs
@@ -77,6 +77,7 @@ extern "C" fn trace_fn(
         cx.frames[cx.idx] = Frame {
             symbol_addr: symaddr as *mut u8,
             exact_position: ip as *mut u8,
+            inline_context: 0,
         };
         cx.idx += 1;
     }
diff --git a/src/libstd/sys/redox/backtrace/tracing.rs b/src/libstd/sys/redox/backtrace/tracing.rs
index 0a174b3c3f5..bb70ca36037 100644
--- a/src/libstd/sys/redox/backtrace/tracing.rs
+++ b/src/libstd/sys/redox/backtrace/tracing.rs
@@ -98,6 +98,7 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
         cx.frames[cx.idx] = Frame {
             symbol_addr: symaddr as *mut u8,
             exact_position: ip as *mut u8,
+            inline_context: 0,
         };
         cx.idx += 1;
     }
diff --git a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
index 400d39cd4bd..6293eeb4ed6 100644
--- a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
@@ -38,6 +38,7 @@ pub fn unwind_backtrace(frames: &mut [Frame])
         *to = Frame {
             exact_position: *from as *mut u8,
             symbol_addr: *from as *mut u8,
+            inline_context: 0,
         };
     }
     Ok((nb_frames as usize, BacktraceContext))
diff --git a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
index 000c08d2e0d..1b92fc0e6ad 100644
--- a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
@@ -98,6 +98,7 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
         cx.frames[cx.idx] = Frame {
             symbol_addr: symaddr as *mut u8,
             exact_position: ip as *mut u8,
+            inline_context: 0,
         };
         cx.idx += 1;
     }
diff --git a/src/libstd/sys/windows/backtrace/mod.rs b/src/libstd/sys/windows/backtrace/mod.rs
index 176891fff23..82498ad4d58 100644
--- a/src/libstd/sys/windows/backtrace/mod.rs
+++ b/src/libstd/sys/windows/backtrace/mod.rs
@@ -56,14 +56,15 @@ pub fn unwind_backtrace(frames: &mut [Frame])
     // Fetch the symbols necessary from dbghelp.dll
     let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn)?;
     let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn)?;
-    let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn)?;
+    let StackWalkEx = sym!(dbghelp, "StackWalkEx", StackWalkExFn)?;
 
     // Allocate necessary structures for doing the stack walk
     let process = unsafe { c::GetCurrentProcess() };
     let thread = unsafe { c::GetCurrentThread() };
     let mut context: c::CONTEXT = unsafe { mem::zeroed() };
     unsafe { c::RtlCaptureContext(&mut context) };
-    let mut frame: c::STACKFRAME64 = unsafe { mem::zeroed() };
+    let mut frame: c::STACKFRAME_EX = unsafe { mem::zeroed() };
+    frame.StackFrameSize = mem::size_of_val(&frame) as c::DWORD;
     let image = init_frame(&mut frame, &context);
 
     let backtrace_context = BacktraceContext {
@@ -79,24 +80,22 @@ pub fn unwind_backtrace(frames: &mut [Frame])
     }
 
     // And now that we're done with all the setup, do the stack walking!
-    // Start from -1 to avoid printing this stack frame, which will
-    // always be exactly the same.
     let mut i = 0;
     unsafe {
         while i < frames.len() &&
-              StackWalk64(image, process, thread, &mut frame, &mut context,
+              StackWalkEx(image, process, thread, &mut frame, &mut context,
                           ptr::null_mut(),
                           ptr::null_mut(),
                           ptr::null_mut(),
-                          ptr::null_mut()) == c::TRUE
+                          ptr::null_mut(),
+                          0) == c::TRUE
         {
-            let addr = frame.AddrPC.Offset;
-            if addr == frame.AddrReturn.Offset || addr == 0 ||
-               frame.AddrReturn.Offset == 0 { break }
+            let addr = (frame.AddrPC.Offset - 1) as *const u8;
 
             frames[i] = Frame {
-                symbol_addr: (addr - 1) as *const u8,
-                exact_position: (addr - 1) as *const u8,
+                symbol_addr: addr,
+                exact_position: addr,
+                inline_context: frame.InlineFrameContext,
             };
             i += 1;
         }
@@ -111,14 +110,14 @@ type SymInitializeFn =
 type SymCleanupFn =
     unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
 
-type StackWalk64Fn =
+type StackWalkExFn =
     unsafe extern "system" fn(c::DWORD, c::HANDLE, c::HANDLE,
-                              *mut c::STACKFRAME64, *mut c::CONTEXT,
+                              *mut c::STACKFRAME_EX, *mut c::CONTEXT,
                               *mut c_void, *mut c_void,
-                              *mut c_void, *mut c_void) -> c::BOOL;
+                              *mut c_void, *mut c_void, c::DWORD) -> c::BOOL;
 
 #[cfg(target_arch = "x86")]
-fn init_frame(frame: &mut c::STACKFRAME64,
+fn init_frame(frame: &mut c::STACKFRAME_EX,
               ctx: &c::CONTEXT) -> c::DWORD {
     frame.AddrPC.Offset = ctx.Eip as u64;
     frame.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
@@ -130,7 +129,7 @@ fn init_frame(frame: &mut c::STACKFRAME64,
 }
 
 #[cfg(target_arch = "x86_64")]
-fn init_frame(frame: &mut c::STACKFRAME64,
+fn init_frame(frame: &mut c::STACKFRAME_EX,
               ctx: &c::CONTEXT) -> c::DWORD {
     frame.AddrPC.Offset = ctx.Rip as u64;
     frame.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
diff --git a/src/libstd/sys/windows/backtrace/printing/msvc.rs b/src/libstd/sys/windows/backtrace/printing/msvc.rs
index 5a49b77af8e..967df1c8a2d 100644
--- a/src/libstd/sys/windows/backtrace/printing/msvc.rs
+++ b/src/libstd/sys/windows/backtrace/printing/msvc.rs
@@ -16,12 +16,12 @@ use sys::c;
 use sys::backtrace::BacktraceContext;
 use sys_common::backtrace::Frame;
 
-type SymFromAddrFn =
-    unsafe extern "system" fn(c::HANDLE, u64, *mut u64,
-                              *mut c::SYMBOL_INFO) -> c::BOOL;
-type SymGetLineFromAddr64Fn =
-    unsafe extern "system" fn(c::HANDLE, u64, *mut u32,
-                              *mut c::IMAGEHLP_LINE64) -> c::BOOL;
+type SymFromInlineContextFn =
+    unsafe extern "system" fn(c::HANDLE, u64, c::ULONG,
+                              *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
+type SymGetLineFromInlineContextFn =
+    unsafe extern "system" fn(c::HANDLE, u64, c::ULONG,
+                              u64, *mut c::DWORD, *mut c::IMAGEHLP_LINE64) -> c::BOOL;
 
 /// Converts a pointer to symbol to its string value.
 pub fn resolve_symname<F>(frame: Frame,
@@ -29,7 +29,9 @@ pub fn resolve_symname<F>(frame: Frame,
                           context: &BacktraceContext) -> io::Result<()>
     where F: FnOnce(Option<&str>) -> io::Result<()>
 {
-    let SymFromAddr = sym!(&context.dbghelp, "SymFromAddr", SymFromAddrFn)?;
+    let SymFromInlineContext = sym!(&context.dbghelp,
+                                    "SymFromInlineContext",
+                                    SymFromInlineContextFn)?;
 
     unsafe {
         let mut info: c::SYMBOL_INFO = mem::zeroed();
@@ -40,12 +42,22 @@ pub fn resolve_symname<F>(frame: Frame,
         info.SizeOfStruct = 88;
 
         let mut displacement = 0u64;
-        let ret = SymFromAddr(context.handle,
-                              frame.symbol_addr as u64,
-                              &mut displacement,
-                              &mut info);
-
-        let symname = if ret == c::TRUE {
+        let ret = SymFromInlineContext(context.handle,
+                                       frame.symbol_addr as u64,
+                                       frame.inline_context,
+                                       &mut displacement,
+                                       &mut info);
+        let valid_range = if ret == c::TRUE &&
+                             frame.symbol_addr as usize >= info.Address as usize {
+            if info.Size != 0 {
+                (frame.symbol_addr as usize) < info.Address as usize + info.Size as usize
+            } else {
+                true
+            }
+        } else {
+            false
+        };
+        let symname = if valid_range {
             let ptr = info.Name.as_ptr() as *const c_char;
             CStr::from_ptr(ptr).to_str().ok()
         } else {
@@ -61,19 +73,21 @@ pub fn foreach_symbol_fileline<F>(frame: Frame,
     -> io::Result<bool>
     where F: FnMut(&[u8], u32) -> io::Result<()>
 {
-    let SymGetLineFromAddr64 = sym!(&context.dbghelp,
-                                    "SymGetLineFromAddr64",
-                                    SymGetLineFromAddr64Fn)?;
+    let SymGetLineFromInlineContext = sym!(&context.dbghelp,
+                                    "SymGetLineFromInlineContext",
+                                    SymGetLineFromInlineContextFn)?;
 
     unsafe {
         let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
         line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
 
         let mut displacement = 0u32;
-        let ret = SymGetLineFromAddr64(context.handle,
-                                       frame.exact_position as u64,
-                                       &mut displacement,
-                                       &mut line);
+        let ret = SymGetLineFromInlineContext(context.handle,
+                                              frame.exact_position as u64,
+                                              frame.inline_context,
+                                              0,
+                                              &mut displacement,
+                                              &mut line);
         if ret == c::TRUE {
             let name = CStr::from_ptr(line.Filename).to_bytes();
             f(name, line.LineNumber as u32)?;
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 66b44f1402f..6d929f21365 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -619,7 +619,7 @@ pub struct ADDRESS64 {
 
 #[repr(C)]
 #[cfg(feature = "backtrace")]
-pub struct STACKFRAME64 {
+pub struct STACKFRAME_EX {
     pub AddrPC: ADDRESS64,
     pub AddrReturn: ADDRESS64,
     pub AddrFrame: ADDRESS64,
@@ -631,6 +631,8 @@ pub struct STACKFRAME64 {
     pub Virtual: BOOL,
     pub Reserved: [u64; 3],
     pub KdHelp: KDHELP64,
+    pub StackFrameSize: DWORD,
+    pub InlineFrameContext: DWORD,
 }
 
 #[repr(C)]
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 36cbce2df75..a364a0392b3 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -41,6 +41,8 @@ pub struct Frame {
     pub exact_position: *const u8,
     /// Address of the enclosing function.
     pub symbol_addr: *const u8,
+    /// Which inlined function is this frame referring to
+    pub inline_context: u32,
 }
 
 /// Max number of frames to print.
@@ -64,6 +66,7 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
     let mut frames = [Frame {
         exact_position: ptr::null(),
         symbol_addr: ptr::null(),
+        inline_context: 0,
     }; MAX_NB_FRAMES];
     let (nb_frames, context) = unwind_backtrace(&mut frames)?;
     let (skipped_before, skipped_after) =