From e8121b3d163f90a8f1cefca07352d3780eed933d Mon Sep 17 00:00:00 2001 From: John Colanduoni Date: Sat, 22 Jul 2017 23:05:47 -0700 Subject: Add libbacktrace support for Apple platforms --- src/libstd/sys/unix/backtrace/mod.rs | 29 ++++++++++++++++++++++++++- src/libstd/sys/unix/backtrace/printing/mod.rs | 6 ++---- 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index bf52da2ed4a..5bb34fe60cc 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -91,15 +91,42 @@ mod tracing; // symbol resolvers: mod printing; -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))] +#[cfg(not(target_os = "emscripten"))] pub mod gnu { use io; use fs; use libc::c_char; + #[cfg(not(any(target_os = "macos", target_os = "ios")))] pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { Err(io::Error::new(io::ErrorKind::Other, "Not implemented")) } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { + use ptr; + use slice; + use ffi::OsStr; + use os::unix::ffi::OsStrExt; + use libc::c_int; + + extern { + fn _NSGetExecutablePath(buf: *mut c_char, + bufsize: *mut u32) -> c_int; + } + unsafe { + let mut bufsize: u32 = 0; + _NSGetExecutablePath(ptr::null_mut(), &mut bufsize); + if bufsize == 0 { return Err(io::Error::last_os_error()); } + let mut buffer: Vec = Vec::with_capacity(bufsize as usize); + let ret = _NSGetExecutablePath(buffer.as_mut_ptr(), &mut bufsize); + if ret != 0 { return Err(io::Error::last_os_error()); } + buffer.set_len(bufsize as usize); + let file = fs::File::open(OsStr::from_bytes( + slice::from_raw_parts(buffer.as_ptr() as *const u8, buffer.len()-1)))?; + Ok((buffer, file)) + } + } } pub struct BacktraceContext; diff --git a/src/libstd/sys/unix/backtrace/printing/mod.rs b/src/libstd/sys/unix/backtrace/printing/mod.rs index 1ae82e01100..857900e1e55 100644 --- a/src/libstd/sys/unix/backtrace/printing/mod.rs +++ b/src/libstd/sys/unix/backtrace/printing/mod.rs @@ -10,13 +10,11 @@ pub use self::imp::{foreach_symbol_fileline, resolve_symname}; -#[cfg(any(target_os = "macos", target_os = "ios", - target_os = "emscripten"))] +#[cfg(target_os = "emscripten")] #[path = "dladdr.rs"] mod imp; -#[cfg(not(any(target_os = "macos", target_os = "ios", - target_os = "emscripten")))] +#[cfg(not(target_os = "emscripten"))] mod imp { pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname}; } -- cgit 1.4.1-3-g733a5 From 09f572b7dccb65ba148d42070f65663c947f93a3 Mon Sep 17 00:00:00 2001 From: John Colanduoni Date: Wed, 9 Aug 2017 22:09:59 -0700 Subject: Use env::current_exe for libbacktrace on macOS --- src/libstd/sys/unix/backtrace/mod.rs | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs index 5bb34fe60cc..b5bf20c747b 100644 --- a/src/libstd/sys/unix/backtrace/mod.rs +++ b/src/libstd/sys/unix/backtrace/mod.rs @@ -104,28 +104,15 @@ pub mod gnu { #[cfg(any(target_os = "macos", target_os = "ios"))] pub fn get_executable_filename() -> io::Result<(Vec, fs::File)> { - use ptr; - use slice; - use ffi::OsStr; + use env; use os::unix::ffi::OsStrExt; - use libc::c_int; - extern { - fn _NSGetExecutablePath(buf: *mut c_char, - bufsize: *mut u32) -> c_int; - } - unsafe { - let mut bufsize: u32 = 0; - _NSGetExecutablePath(ptr::null_mut(), &mut bufsize); - if bufsize == 0 { return Err(io::Error::last_os_error()); } - let mut buffer: Vec = Vec::with_capacity(bufsize as usize); - let ret = _NSGetExecutablePath(buffer.as_mut_ptr(), &mut bufsize); - if ret != 0 { return Err(io::Error::last_os_error()); } - buffer.set_len(bufsize as usize); - let file = fs::File::open(OsStr::from_bytes( - slice::from_raw_parts(buffer.as_ptr() as *const u8, buffer.len()-1)))?; - Ok((buffer, file)) - } + let filename = env::current_exe()?; + let file = fs::File::open(&filename)?; + let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter() + .map(|&x| x as c_char).collect(); + filename_cstr.push(0); // Null terminate + Ok((filename_cstr, file)) } } -- cgit 1.4.1-3-g733a5 From 7169fe57d66dedad21f2dcf4c615feb9ab7d3f5a Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 2 Sep 2017 02:09:39 +0800 Subject: Fallback to dladdr-based resolve_symbol if backtrace failed. This programs compiled without -g on macOS still provide the resolve to actual symbols, instead of `` everywhere. --- src/libstd/sys/unix/backtrace/printing/dladdr.rs | 8 ------ src/libstd/sys/unix/backtrace/printing/mod.rs | 35 ++++++++++++++++++++---- 2 files changed, 29 insertions(+), 14 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/backtrace/printing/dladdr.rs b/src/libstd/sys/unix/backtrace/printing/dladdr.rs index 05a071a7978..3a3912af021 100644 --- a/src/libstd/sys/unix/backtrace/printing/dladdr.rs +++ b/src/libstd/sys/unix/backtrace/printing/dladdr.rs @@ -31,14 +31,6 @@ pub fn resolve_symname(frame: Frame, } } -pub fn foreach_symbol_fileline(_symbol_addr: Frame, - _f: F, - _: &BacktraceContext) -> io::Result - where F: FnMut(&[u8], libc::c_int) -> io::Result<()> -{ - Ok(false) -} - #[repr(C)] struct Dl_info { dli_fname: *const libc::c_char, diff --git a/src/libstd/sys/unix/backtrace/printing/mod.rs b/src/libstd/sys/unix/backtrace/printing/mod.rs index 857900e1e55..8bd2d9eccd8 100644 --- a/src/libstd/sys/unix/backtrace/printing/mod.rs +++ b/src/libstd/sys/unix/backtrace/printing/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,13 +8,36 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::imp::{foreach_symbol_fileline, resolve_symname}; +mod dladdr; + +use sys::backtrace::BacktraceContext; +use sys_common::backtrace::Frame; +use io; + +#[cfg(target_os = "emscripten")] +pub use self::dladdr::resolve_symname; #[cfg(target_os = "emscripten")] -#[path = "dladdr.rs"] -mod imp; +pub fn foreach_symbol_fileline(_: Frame, _: F, _: &BacktraceContext) -> io::Result +where + F: FnMut(&[u8], ::libc::c_int) -> io::Result<()> +{ + Ok(false) +} + +#[cfg(not(target_os = "emscripten"))] +pub use sys_common::gnu::libbacktrace::foreach_symbol_fileline; #[cfg(not(target_os = "emscripten"))] -mod imp { - pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname}; +pub fn resolve_symname(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()> +where + F: FnOnce(Option<&str>) -> io::Result<()> +{ + ::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| { + if symname.is_some() { + callback(symname) + } else { + dladdr::resolve_symname(frame, callback, bc) + } + }, bc) } -- cgit 1.4.1-3-g733a5