about summary refs log tree commit diff
path: root/src/libstd/sys_common/gnu
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-01-28 20:32:56 +0000
committerbors <bors@rust-lang.org>2017-01-28 20:32:56 +0000
commit1491e0425911806f2612f05ee8caf21666447128 (patch)
treeea70520dbf0d73ef2fa82d91074776160517b8bb /src/libstd/sys_common/gnu
parentc81c1d6a41babf7e34120625727211cad7b40b87 (diff)
parentab21314c3fbf093c92123abee62101d15846c1e2 (diff)
downloadrust-1491e0425911806f2612f05ee8caf21666447128.tar.gz
rust-1491e0425911806f2612f05ee8caf21666447128.zip
Auto merge of #39234 - segevfiner:fix-backtraces-on-windows-gnu, r=petrochenkov
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

Note though that this isn't that pretty...

I had to implement a `WideCharToMultiByte` wrapper function to convert to the ANSI code page. This will work better than only allowing ASCII provided that the ANSI code page is set to the user's local language, which is often the case.

Also, please make sure that I didn't break the Unix build.
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..d464a13ad1d 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::gnu::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
     }