Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ddd123e

Browse files
committedSep 9, 2017
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).
2 parents 18366f4 + aa6bd11 commit ddd123e

File tree

10 files changed

+1477
-24
lines changed

10 files changed

+1477
-24
lines changed
 

‎src/libbacktrace/configure

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11844,6 +11844,9 @@ elf*) FORMAT_FILE="elf.lo" ;;
1184411844
pecoff) FORMAT_FILE="pecoff.lo"
1184511845
backtrace_supports_data=no
1184611846
;;
11847+
macho*) FORMAT_FILE="macho.lo"
11848+
backtrace_supports_data=no
11849+
;;
1184711850
*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not determine output file type" >&5
1184811851
$as_echo "$as_me: WARNING: could not determine output file type" >&2;}
1184911852
FORMAT_FILE="unknown.lo"

‎src/libbacktrace/configure.ac

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ elf*) FORMAT_FILE="elf.lo" ;;
231231
pecoff) FORMAT_FILE="pecoff.lo"
232232
backtrace_supports_data=no
233233
;;
234+
macho*) FORMAT_FILE="macho.lo"
235+
backtrace_supports_data=no
236+
;;
234237
*) AC_MSG_WARN([could not determine output file type])
235238
FORMAT_FILE="unknown.lo"
236239
backtrace_supported=no

‎src/libbacktrace/filetype.awk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,9 @@
33
/\177ELF\002/ { if (NR == 1) { print "elf64"; exit } }
44
/\114\001/ { if (NR == 1) { print "pecoff"; exit } }
55
/\144\206/ { if (NR == 1) { print "pecoff"; exit } }
6+
/\xFE\xED\xFA\xCE/ { if (NR == 1) { print "macho32"; exit } }
7+
/\xCE\xFA\xED\xFE/ { if (NR == 1) { print "macho32"; exit } }
8+
/\xFE\xED\xFA\xCF/ { if (NR == 1) { print "macho64"; exit } }
9+
/\xCF\xFA\xED\xFE/ { if (NR == 1) { print "macho64"; exit } }
10+
/\xCA\xFE\xBA\xBE/ { if (NR == 1) { print "macho-fat"; exit } }
11+
/\xBE\xBA\xFE\xCA/ { if (NR == 1) { print "macho-fat"; exit } }

‎src/libbacktrace/macho.c

Lines changed: 1416 additions & 0 deletions
Large diffs are not rendered by default.

‎src/libstd/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use build_helper::{run, native_lib_boilerplate};
2020
fn main() {
2121
let target = env::var("TARGET").expect("TARGET was not set");
2222
let host = env::var("HOST").expect("HOST was not set");
23-
if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") &&
23+
if cfg!(feature = "backtrace") && !target.contains("msvc") &&
2424
!target.contains("emscripten") && !target.contains("fuchsia") {
2525
let _ = build_libbacktrace(&host, &target);
2626
}

‎src/libstd/sys/unix/backtrace/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,29 @@ mod tracing;
9191
// symbol resolvers:
9292
mod printing;
9393

94-
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))]
94+
#[cfg(not(target_os = "emscripten"))]
9595
pub mod gnu {
9696
use io;
9797
use fs;
9898
use libc::c_char;
9999

100+
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
100101
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
101102
Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
102103
}
104+
105+
#[cfg(any(target_os = "macos", target_os = "ios"))]
106+
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
107+
use env;
108+
use os::unix::ffi::OsStrExt;
109+
110+
let filename = env::current_exe()?;
111+
let file = fs::File::open(&filename)?;
112+
let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter()
113+
.map(|&x| x as c_char).collect();
114+
filename_cstr.push(0); // Null terminate
115+
Ok((filename_cstr, file))
116+
}
103117
}
104118

105119
pub struct BacktraceContext;

‎src/libstd/sys/unix/backtrace/printing/dladdr.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@ pub fn resolve_symname<F>(frame: Frame,
3131
}
3232
}
3333

34-
pub fn foreach_symbol_fileline<F>(_symbol_addr: Frame,
35-
_f: F,
36-
_: &BacktraceContext) -> io::Result<bool>
37-
where F: FnMut(&[u8], libc::c_int) -> io::Result<()>
38-
{
39-
Ok(false)
40-
}
41-
4234
#[repr(C)]
4335
struct Dl_info {
4436
dli_fname: *const libc::c_char,
Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,15 +8,36 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
pub use self::imp::{foreach_symbol_fileline, resolve_symname};
11+
mod dladdr;
1212

13-
#[cfg(any(target_os = "macos", target_os = "ios",
14-
target_os = "emscripten"))]
15-
#[path = "dladdr.rs"]
16-
mod imp;
13+
use sys::backtrace::BacktraceContext;
14+
use sys_common::backtrace::Frame;
15+
use io;
1716

18-
#[cfg(not(any(target_os = "macos", target_os = "ios",
19-
target_os = "emscripten")))]
20-
mod imp {
21-
pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
17+
#[cfg(target_os = "emscripten")]
18+
pub use self::dladdr::resolve_symname;
19+
20+
#[cfg(target_os = "emscripten")]
21+
pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
22+
where
23+
F: FnMut(&[u8], ::libc::c_int) -> io::Result<()>
24+
{
25+
Ok(false)
26+
}
27+
28+
#[cfg(not(target_os = "emscripten"))]
29+
pub use sys_common::gnu::libbacktrace::foreach_symbol_fileline;
30+
31+
#[cfg(not(target_os = "emscripten"))]
32+
pub fn resolve_symname<F>(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()>
33+
where
34+
F: FnOnce(Option<&str>) -> io::Result<()>
35+
{
36+
::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| {
37+
if symname.is_some() {
38+
callback(symname)
39+
} else {
40+
dladdr::resolve_symname(frame, callback, bc)
41+
}
42+
}, bc)
2243
}

‎src/libstd/sys_common/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub use sys::net;
5151
pub mod net;
5252

5353
#[cfg(feature = "backtrace")]
54-
#[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "emscripten"))),
54+
#[cfg(any(all(unix, not(target_os = "emscripten")),
5555
all(windows, target_env = "gnu"),
5656
target_os = "redox"))]
5757
pub mod gnu;

‎src/test/run-pass/backtrace-debuginfo.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ macro_rules! dump_and_die {
3333
($($pos:expr),*) => ({
3434
// FIXME(#18285): we cannot include the current position because
3535
// the macro span takes over the last frame's file/line.
36-
if cfg!(any(target_os = "macos",
37-
target_os = "ios",
38-
target_os = "android",
36+
if cfg!(any(target_os = "android",
3937
all(target_os = "linux", target_arch = "arm"),
4038
target_os = "freebsd",
4139
target_os = "dragonfly",

0 commit comments

Comments
 (0)
Please sign in to comment.