about summary refs log tree commit diff
path: root/src/libstd/sys_common/gnu
diff options
context:
space:
mode:
authorSegev Finer <segev208@gmail.com>2017-01-22 00:28:17 +0200
committerSegev Finer <segev208@gmail.com>2017-01-24 23:10:00 +0200
commit4186037aaa1a6aa3ba15a10130b424e7508bd276 (patch)
treeebd6d096512c8bf550f774dcf89dce910f9dccb3 /src/libstd/sys_common/gnu
parentfe597dc9a9f325de9b2b11d69e190e1c22c4e7dc (diff)
downloadrust-4186037aaa1a6aa3ba15a10130b424e7508bd276.tar.gz
rust-4186037aaa1a6aa3ba15a10130b424e7508bd276.zip
Make backtraces work on Windows GNU targets again.
This is done by adding a function that can return a filename
to pass to backtrace_create_state. The filename is obtained in
a safe way by first getting the filename, locking the file so it can't
be moved, and then getting the filename again and making sure it's the same.

See: https://github.com/rust-lang/rust/pull/37359#issuecomment-260123399
Issue: #33985
Diffstat (limited to 'src/libstd/sys_common/gnu')
-rw-r--r--src/libstd/sys_common/gnu/libbacktrace.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs
index b5802afc109..94d206f3ac3 100644
--- a/src/libstd/sys_common/gnu/libbacktrace.rs
+++ b/src/libstd/sys_common/gnu/libbacktrace.rs
@@ -16,6 +16,7 @@ use sys_common::backtrace::{output, output_fileline};
 pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
              symaddr: *mut libc::c_void) -> io::Result<()> {
     use ffi::CStr;
+    use mem;
     use ptr;
 
     ////////////////////////////////////////////////////////////////////////
@@ -124,7 +125,21 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
     unsafe fn init_state() -> *mut backtrace_state {
         static mut STATE: *mut backtrace_state = ptr::null_mut();
         if !STATE.is_null() { return STATE }
-        STATE = backtrace_create_state(ptr::null(), 0, error_cb,
+
+        let filename = match ::sys::backtrace::get_executable_filename() {
+            Ok((filename, file)) => {
+                // filename is purposely leaked here since libbacktrace requires
+                // it to stay allocated permanently, file is also leaked so that
+                // the file stays locked
+                let filename_ptr = filename.as_ptr();
+                mem::forget(filename);
+                mem::forget(file);
+                filename_ptr
+            },
+            Err(_) => ptr::null(),
+        };
+
+        STATE = backtrace_create_state(filename, 0, error_cb,
                                        ptr::null_mut());
         STATE
     }