From 4186037aaa1a6aa3ba15a10130b424e7508bd276 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sun, 22 Jan 2017 00:28:17 +0200 Subject: [PATCH 1/4] 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 --- src/libstd/sys/unix/backtrace/mod.rs | 7 ++++ src/libstd/sys/windows/backtrace.rs | 48 +++++++++++++++++++++++ src/libstd/sys/windows/c.rs | 23 +++++++++++ src/libstd/sys/windows/mod.rs | 46 ++++++++++++++++++++++ src/libstd/sys_common/gnu/libbacktrace.rs | 17 +++++++- src/test/run-pass/backtrace-debuginfo.rs | 2 - src/test/run-pass/backtrace.rs | 4 -- 7 files changed, 140 insertions(+), 7 deletions(-) diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index d7c05e513f68c..e3f1b23f7a24b 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -83,9 +83,16 @@ /// to symbols. This is a bit of a hokey implementation as-is, but it works for /// all unix platforms we support right now, so it at least gets the job done. +use io; +use fs; + pub use self::tracing::write; // tracing impls: mod tracing; // symbol resolvers: mod printing; + +pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) +} diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index 82a44c1c1103b..e6182cda58a28 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -30,9 +30,13 @@ use io; use libc::c_void; use mem; use ptr; +use path::PathBuf; +use fs::{OpenOptions, File}; +use sys::ext::fs::OpenOptionsExt; use sys::c; use sys::dynamic_lib::DynamicLibrary; use sys::mutex::Mutex; +use sys::handle::Handle; macro_rules! sym { ($lib:expr, $e:expr, $t:ident) => ( @@ -157,3 +161,47 @@ unsafe fn _write(w: &mut Write) -> io::Result<()> { Ok(()) } + +fn query_full_process_image_name() -> io::Result { + unsafe { + let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION, + c::FALSE, + c::GetCurrentProcessId())); + super::fill_utf16_buf(|buf, mut sz| { + if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 { + 0 + } else { + sz + } + }, super::os2path) + } +} + +fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { + // We query the current image name, open the file without FILE_SHARE_DELETE so it + // can't be moved and then get the current image name again. If the names are the + // same than we have successfully locked the file + let image_name1 = query_full_process_image_name()?; + let file = OpenOptions::new() + .read(true) + .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE) + .open(&image_name1)?; + let image_name2 = query_full_process_image_name()?; + + if image_name1 != image_name2 { + return Err(io::Error::new(io::ErrorKind::Other, + "executable moved while trying to lock it")); + } + + Ok((image_name1, file)) +} + +// Get the executable filename for libbacktrace +// This returns the path in the ANSI code page and a File which should remain open +// for as long as the path should remain valid +pub fn get_executable_filename() -> io::Result<(Vec, File)> { + let (executable, file) = lock_and_get_executable_filename()?; + let u16_executable = super::to_u16s(executable.into_os_string())?; + Ok((super::wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, + &u16_executable, true)?, file)) +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index dc7b2fc9a6bab..c6fac6d1759b1 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -69,6 +69,7 @@ pub type LPWCH = *mut WCHAR; pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub type LPWSADATA = *mut WSADATA; pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; +pub type LPSTR = *mut CHAR; pub type LPWSTR = *mut WCHAR; pub type LPFILETIME = *mut FILETIME; @@ -157,6 +158,7 @@ pub const WSAECONNREFUSED: c_int = 10061; pub const MAX_PROTOCOL_CHAIN: DWORD = 7; +pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400; pub const TOKEN_READ: DWORD = 0x20008; pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8; @@ -218,6 +220,10 @@ pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200; pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400; pub const STARTF_USESTDHANDLES: DWORD = 0x00000100; +pub const CP_ACP: UINT = 0; + +pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400; + pub const AF_INET: c_int = 2; pub const AF_INET6: c_int = 23; pub const SD_BOTH: c_int = 2; @@ -888,6 +894,9 @@ extern "system" { pNumArgs: *mut c_int) -> *mut *mut u16; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; + pub fn OpenProcess(dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwProcessId: DWORD) -> HANDLE; pub fn OpenProcessToken(ProcessHandle: HANDLE, DesiredAccess: DWORD, TokenHandle: *mut HANDLE) -> BOOL; @@ -973,6 +982,14 @@ extern "system" { pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL; pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn WideCharToMultiByte(CodePage: UINT, + dwFlags: DWORD, + lpWideCharStr: LPCWSTR, + cchWideChar: c_int, + lpMultiByteStr: LPSTR, + cbMultiByte: c_int, + lpDefaultChar: LPCSTR, + lpUsedDefaultChar: LPBOOL) -> c_int; pub fn closesocket(socket: SOCKET) -> c_int; pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, @@ -1136,6 +1153,12 @@ compat_fn! { _dwFlags: DWORD) -> DWORD { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } + pub fn QueryFullProcessImageNameW(_hProcess: HANDLE, + _dwFlags: DWORD, + _lpExeName: LPWSTR, + _lpdwSize: LPDWORD) -> BOOL { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index defc41c5f46a3..4468cf574b38a 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -10,6 +10,7 @@ #![allow(missing_docs, bad_style)] +use ptr; use ffi::{OsStr, OsString}; use io::{self, ErrorKind}; use os::windows::ffi::{OsStrExt, OsStringExt}; @@ -171,6 +172,51 @@ fn os2path(s: &[u16]) -> PathBuf { PathBuf::from(OsString::from_wide(s)) } +fn wide_char_to_multi_byte(code_page: u32, + flags: u32, + s: &[u16], + no_default_char: bool) + -> io::Result> { + unsafe { + let mut size = c::WideCharToMultiByte(code_page, + flags, + s.as_ptr(), + s.len() as i32, + ptr::null_mut(), + 0, + ptr::null(), + ptr::null_mut()); + if size == 0 { + return Err(io::Error::last_os_error()); + } + + let mut buf = Vec::with_capacity(size as usize); + buf.set_len(size as usize); + + let mut used_default_char = c::FALSE; + size = c::WideCharToMultiByte(code_page, + flags, + s.as_ptr(), + s.len() as i32, + buf.as_mut_ptr(), + buf.len() as i32, + ptr::null(), + if no_default_char { &mut used_default_char } + else { ptr::null_mut() }); + if size == 0 { + return Err(io::Error::last_os_error()); + } + if no_default_char && used_default_char == c::TRUE { + return Err(io::Error::new(io::ErrorKind::InvalidData, + "string cannot be converted to requested code page")); + } + + buf.set_len(size as usize); + + Ok(buf) + } +} + pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { match v.iter().position(|c| *c == 0) { // don't include the 0 diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs index b5802afc10943..94d206f3ac3c1 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 } diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 72cf109fd5974..626eccfc9ec86 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -37,7 +37,6 @@ macro_rules! dump_and_die { target_os = "ios", target_os = "android", all(target_os = "linux", target_arch = "arm"), - target_os = "windows", target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", @@ -173,4 +172,3 @@ fn main() { run_test(&args[0]); } } - diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 75c665b04a123..834ce984e6632 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -104,10 +104,6 @@ fn runtest(me: &str) { } fn main() { - if cfg!(windows) && cfg!(target_env = "gnu") { - return - } - let args: Vec = env::args().collect(); if args.len() >= 2 && args[1] == "fail" { foo(); From 450554ebf139d0b6ecde80f17c2ef89ff7de78bb Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 27 Jan 2017 11:33:24 +0200 Subject: [PATCH 2/4] Attempt at fixing dead code lints --- src/libstd/sys/unix/backtrace/mod.rs | 13 +++-- src/libstd/sys/windows/backtrace.rs | 52 ++----------------- src/libstd/sys/windows/backtrace_gnu.rs | 61 +++++++++++++++++++++++ src/libstd/sys/windows/c.rs | 45 +++++++++++------ src/libstd/sys/windows/mod.rs | 1 + src/libstd/sys_common/gnu/libbacktrace.rs | 2 +- 6 files changed, 106 insertions(+), 68 deletions(-) create mode 100644 src/libstd/sys/windows/backtrace_gnu.rs diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index e3f1b23f7a24b..62e9c24ac3045 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -83,9 +83,6 @@ /// to symbols. This is a bit of a hokey implementation as-is, but it works for /// all unix platforms we support right now, so it at least gets the job done. -use io; -use fs; - pub use self::tracing::write; // tracing impls: @@ -93,6 +90,12 @@ mod tracing; // symbol resolvers: mod printing; -pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { - Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) +#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))] +pub mod gnu { + use io; + use fs; + + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) + } } diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index e6182cda58a28..94aaf439f3d57 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -30,13 +30,9 @@ use io; use libc::c_void; use mem; use ptr; -use path::PathBuf; -use fs::{OpenOptions, File}; -use sys::ext::fs::OpenOptionsExt; use sys::c; use sys::dynamic_lib::DynamicLibrary; use sys::mutex::Mutex; -use sys::handle::Handle; macro_rules! sym { ($lib:expr, $e:expr, $t:ident) => ( @@ -55,6 +51,10 @@ mod printing; #[path = "printing/gnu.rs"] mod printing; +#[cfg(target_env = "gnu")] +#[path = "backtrace_gnu.rs"] +pub mod gnu; + type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL; @@ -161,47 +161,3 @@ unsafe fn _write(w: &mut Write) -> io::Result<()> { Ok(()) } - -fn query_full_process_image_name() -> io::Result { - unsafe { - let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION, - c::FALSE, - c::GetCurrentProcessId())); - super::fill_utf16_buf(|buf, mut sz| { - if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 { - 0 - } else { - sz - } - }, super::os2path) - } -} - -fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { - // We query the current image name, open the file without FILE_SHARE_DELETE so it - // can't be moved and then get the current image name again. If the names are the - // same than we have successfully locked the file - let image_name1 = query_full_process_image_name()?; - let file = OpenOptions::new() - .read(true) - .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE) - .open(&image_name1)?; - let image_name2 = query_full_process_image_name()?; - - if image_name1 != image_name2 { - return Err(io::Error::new(io::ErrorKind::Other, - "executable moved while trying to lock it")); - } - - Ok((image_name1, file)) -} - -// Get the executable filename for libbacktrace -// This returns the path in the ANSI code page and a File which should remain open -// for as long as the path should remain valid -pub fn get_executable_filename() -> io::Result<(Vec, File)> { - let (executable, file) = lock_and_get_executable_filename()?; - let u16_executable = super::to_u16s(executable.into_os_string())?; - Ok((super::wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, - &u16_executable, true)?, file)) -} diff --git a/src/libstd/sys/windows/backtrace_gnu.rs b/src/libstd/sys/windows/backtrace_gnu.rs new file mode 100644 index 0000000000000..8282174a59efe --- /dev/null +++ b/src/libstd/sys/windows/backtrace_gnu.rs @@ -0,0 +1,61 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use io; +use sys::c; +use path::PathBuf; +use fs::{OpenOptions, File}; +use sys::ext::fs::OpenOptionsExt; +use sys::handle::Handle; +use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte}; + +fn query_full_process_image_name() -> io::Result { + unsafe { + let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION, + c::FALSE, + c::GetCurrentProcessId())); + fill_utf16_buf(|buf, mut sz| { + if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 { + 0 + } else { + sz + } + }, os2path) + } +} + +fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { + // We query the current image name, open the file without FILE_SHARE_DELETE so it + // can't be moved and then get the current image name again. If the names are the + // same than we have successfully locked the file + let image_name1 = query_full_process_image_name()?; + let file = OpenOptions::new() + .read(true) + .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE) + .open(&image_name1)?; + let image_name2 = query_full_process_image_name()?; + + if image_name1 != image_name2 { + return Err(io::Error::new(io::ErrorKind::Other, + "executable moved while trying to lock it")); + } + + Ok((image_name1, file)) +} + +// Get the executable filename for libbacktrace +// This returns the path in the ANSI code page and a File which should remain open +// for as long as the path should remain valid +pub fn get_executable_filename() -> io::Result<(Vec, File)> { + let (executable, file) = lock_and_get_executable_filename()?; + let u16_executable = to_u16s(executable.into_os_string())?; + Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, + &u16_executable, true)?, file)) +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index c6fac6d1759b1..1b29bf73c7aec 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -158,7 +158,6 @@ pub const WSAECONNREFUSED: c_int = 10061; pub const MAX_PROTOCOL_CHAIN: DWORD = 7; -pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400; pub const TOKEN_READ: DWORD = 0x20008; pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8; @@ -220,10 +219,6 @@ pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200; pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400; pub const STARTF_USESTDHANDLES: DWORD = 0x00000100; -pub const CP_ACP: UINT = 0; - -pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400; - pub const AF_INET: c_int = 2; pub const AF_INET6: c_int = 23; pub const SD_BOTH: c_int = 2; @@ -894,9 +889,6 @@ extern "system" { pNumArgs: *mut c_int) -> *mut *mut u16; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; - pub fn OpenProcess(dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwProcessId: DWORD) -> HANDLE; pub fn OpenProcessToken(ProcessHandle: HANDLE, DesiredAccess: DWORD, TokenHandle: *mut HANDLE) -> BOOL; @@ -1153,12 +1145,6 @@ compat_fn! { _dwFlags: DWORD) -> DWORD { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } - pub fn QueryFullProcessImageNameW(_hProcess: HANDLE, - _dwFlags: DWORD, - _lpExeName: LPWSTR, - _lpdwSize: LPDWORD) -> BOOL { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 - } pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 } @@ -1201,3 +1187,34 @@ compat_fn! { panic!("rwlocks not available") } } + +#[cfg(target_env = "gnu")] +mod gnu { + use super::*; + + pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400; + + pub const CP_ACP: UINT = 0; + + pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400; + + extern "system" { + pub fn OpenProcess(dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwProcessId: DWORD) -> HANDLE; + } + + compat_fn! { + kernel32: + + pub fn QueryFullProcessImageNameW(_hProcess: HANDLE, + _dwFlags: DWORD, + _lpExeName: LPWSTR, + _lpdwSize: LPDWORD) -> BOOL { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 + } + } +} + +#[cfg(target_env = "gnu")] +pub use self::gnu::*; diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 4468cf574b38a..4424c6c6136c5 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -172,6 +172,7 @@ fn os2path(s: &[u16]) -> PathBuf { PathBuf::from(OsString::from_wide(s)) } +#[allow(dead_code)] // Only used in backtrace::gnu::get_executable_filename() fn wide_char_to_multi_byte(code_page: u32, flags: u32, s: &[u16], diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs index 94d206f3ac3c1..d464a13ad1d3f 100644 --- a/src/libstd/sys_common/gnu/libbacktrace.rs +++ b/src/libstd/sys_common/gnu/libbacktrace.rs @@ -126,7 +126,7 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, static mut STATE: *mut backtrace_state = ptr::null_mut(); if !STATE.is_null() { return STATE } - let filename = match ::sys::backtrace::get_executable_filename() { + 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 From 1b4a6c86fa2acc4385c3c420773484d61ecc22b8 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sat, 28 Jan 2017 01:01:16 +0200 Subject: [PATCH 3/4] Use libc::c_char instead of i8 due to platforms with unsigned char --- src/libstd/sys/unix/backtrace/mod.rs | 3 ++- src/libstd/sys/windows/backtrace_gnu.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index 62e9c24ac3045..1eef89bf66f74 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -94,8 +94,9 @@ mod printing; pub mod gnu { use io; use fs; + use libc::c_char; - pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) } } diff --git a/src/libstd/sys/windows/backtrace_gnu.rs b/src/libstd/sys/windows/backtrace_gnu.rs index 8282174a59efe..f0d29dd4178d1 100644 --- a/src/libstd/sys/windows/backtrace_gnu.rs +++ b/src/libstd/sys/windows/backtrace_gnu.rs @@ -10,6 +10,7 @@ use io; use sys::c; +use libc::c_char; use path::PathBuf; use fs::{OpenOptions, File}; use sys::ext::fs::OpenOptionsExt; @@ -53,7 +54,7 @@ fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> { // Get the executable filename for libbacktrace // This returns the path in the ANSI code page and a File which should remain open // for as long as the path should remain valid -pub fn get_executable_filename() -> io::Result<(Vec, File)> { +pub fn get_executable_filename() -> io::Result<(Vec, File)> { let (executable, file) = lock_and_get_executable_filename()?; let u16_executable = to_u16s(executable.into_os_string())?; Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS, From ab21314c3fbf093c92123abee62101d15846c1e2 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Sat, 28 Jan 2017 21:52:31 +0200 Subject: [PATCH 4/4] Disable backtrace tests on i686-pc-windows-gnu since it's broken by FPO --- src/test/run-pass/backtrace-debuginfo.rs | 1 + src/test/run-pass/backtrace.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 626eccfc9ec86..015ba75d432ad 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -37,6 +37,7 @@ macro_rules! dump_and_die { target_os = "ios", target_os = "android", all(target_os = "linux", target_arch = "arm"), + all(target_os = "windows", target_pointer_width = "32"), target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 834ce984e6632..e892f5e7728b3 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -104,6 +104,10 @@ fn runtest(me: &str) { } fn main() { + if cfg!(windows) && cfg!(target_env = "gnu") && cfg!(target_pointer_width = "32") { + return + } + let args: Vec = env::args().collect(); if args.len() >= 2 && args[1] == "fail" { foo();