about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-09-09 17:32:13 +0000
committerbors <bors@rust-lang.org>2017-09-09 17:32:13 +0000
commitddd123ed9a35ec76103d42cecf322ee8d2896bf9 (patch)
tree03c5d4c8020c62bc36f0486e65de8cae0eaf91a9 /src/libstd
parent18366f4e8aaec1d46282cf0a6e0fe1a0ab202530 (diff)
parentaa6bd117bbe05930476b4aec1001fff77ce66348 (diff)
downloadrust-ddd123ed9a35ec76103d42cecf322ee8d2896bf9.tar.gz
rust-ddd123ed9a35ec76103d42cecf322ee8d2896bf9.zip
Auto merge of #44251 - kennytm:osx-backtrace, r=alexcrichton
Add libbacktrace support for Apple platforms (resubmitted)

Resubmitting #43422 rebased on the current master (cc @JohnColanduoni).

I have added an additional commit to fallback to `dladdr`-based `resolve_symbol` if `libbacktrace` returns `None`, otherwise the stack trace will be full of `<unknown>` when you forget to pass the `-g` flag (actually it seems — at least on macOS — the `dladdr` symbol is more accurate than the `libbacktrace` one).
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/build.rs2
-rw-r--r--src/libstd/sys/unix/backtrace/mod.rs16
-rw-r--r--src/libstd/sys/unix/backtrace/printing/dladdr.rs8
-rw-r--r--src/libstd/sys/unix/backtrace/printing/mod.rs41
-rw-r--r--src/libstd/sys_common/mod.rs2
5 files changed, 48 insertions, 21 deletions
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 7dec7eb77e1..ebf07eb0423 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -20,7 +20,7 @@ use build_helper::{run, native_lib_boilerplate};
 fn main() {
     let target = env::var("TARGET").expect("TARGET was not set");
     let host = env::var("HOST").expect("HOST was not set");
-    if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") &&
+    if cfg!(feature = "backtrace") && !target.contains("msvc") &&
         !target.contains("emscripten") && !target.contains("fuchsia") {
         let _ = build_libbacktrace(&host, &target);
     }
diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs
index bf52da2ed4a..b5bf20c747b 100644
--- a/src/libstd/sys/unix/backtrace/mod.rs
+++ b/src/libstd/sys/unix/backtrace/mod.rs
@@ -91,15 +91,29 @@ 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<c_char>, 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<c_char>, fs::File)> {
+        use env;
+        use os::unix::ffi::OsStrExt;
+
+        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))
+    }
 }
 
 pub struct BacktraceContext;
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<F>(frame: Frame,
     }
 }
 
-pub fn foreach_symbol_fileline<F>(_symbol_addr: Frame,
-                                  _f: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    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 1ae82e01100..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,15 +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;
 
-#[cfg(any(target_os = "macos", target_os = "ios",
-          target_os = "emscripten"))]
-#[path = "dladdr.rs"]
-mod imp;
+use sys::backtrace::BacktraceContext;
+use sys_common::backtrace::Frame;
+use io;
 
-#[cfg(not(any(target_os = "macos", target_os = "ios",
-              target_os = "emscripten")))]
-mod imp {
-    pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
+#[cfg(target_os = "emscripten")]
+pub use self::dladdr::resolve_symname;
+
+#[cfg(target_os = "emscripten")]
+pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
+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"))]
+pub fn resolve_symname<F>(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)
 }
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index ccd4b91a7b7..30241819bd5 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -51,7 +51,7 @@ pub use sys::net;
 pub mod net;
 
 #[cfg(feature = "backtrace")]
-#[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))),
+#[cfg(any(all(unix, not(target_os = "emscripten")),
           all(windows, target_env = "gnu"),
           target_os = "redox"))]
 pub mod gnu;