From 9d67d5a71dafe105167acf0e8b960f5aa118652b Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 3 Aug 2017 22:49:46 -0700 Subject: [PATCH] Simplify Redox backtrace/ to not include non-Redox implementations --- src/libstd/sys/redox/backtrace/mod.rs | 76 +------------------ .../backtrace/{tracing/mod.rs => printing.rs} | 11 +-- .../sys/redox/backtrace/printing/dladdr.rs | 53 ------------- .../sys/redox/backtrace/printing/mod.rs | 22 ------ .../{tracing/gcc_s.rs => tracing.rs} | 0 .../redox/backtrace/tracing/backtrace_fn.rs | 48 ------------ 6 files changed, 3 insertions(+), 207 deletions(-) rename src/libstd/sys/redox/backtrace/{tracing/mod.rs => printing.rs} (60%) delete mode 100644 src/libstd/sys/redox/backtrace/printing/dladdr.rs delete mode 100644 src/libstd/sys/redox/backtrace/printing/mod.rs rename src/libstd/sys/redox/backtrace/{tracing/gcc_s.rs => tracing.rs} (100%) delete mode 100644 src/libstd/sys/redox/backtrace/tracing/backtrace_fn.rs diff --git a/src/libstd/sys/redox/backtrace/mod.rs b/src/libstd/sys/redox/backtrace/mod.rs index 2171494c499..40b957d847b 100644 --- a/src/libstd/sys/redox/backtrace/mod.rs +++ b/src/libstd/sys/redox/backtrace/mod.rs @@ -8,80 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/// Backtrace support built on libgcc with some extra OS-specific support -/// -/// Some methods of getting a backtrace: -/// -/// * The backtrace() functions on unix. It turns out this doesn't work very -/// well for green threads on macOS, and the address to symbol portion of it -/// suffers problems that are described below. -/// -/// * Using libunwind. This is more difficult than it sounds because libunwind -/// isn't installed everywhere by default. It's also a bit of a hefty library, -/// so possibly not the best option. When testing, libunwind was excellent at -/// getting both accurate backtraces and accurate symbols across platforms. -/// This route was not chosen in favor of the next option, however. -/// -/// * We're already using libgcc_s for exceptions in rust (triggering thread -/// unwinding and running destructors on the stack), and it turns out that it -/// conveniently comes with a function that also gives us a backtrace. All of -/// these functions look like _Unwind_*, but it's not quite the full -/// repertoire of the libunwind API. Due to it already being in use, this was -/// the chosen route of getting a backtrace. -/// -/// After choosing libgcc_s for backtraces, the sad part is that it will only -/// give us a stack trace of instruction pointers. Thankfully these instruction -/// pointers are accurate (they work for green and native threads), but it's -/// then up to us again to figure out how to translate these addresses to -/// symbols. As with before, we have a few options. Before, that, a little bit -/// of an interlude about symbols. This is my very limited knowledge about -/// symbol tables, and this information is likely slightly wrong, but the -/// general idea should be correct. -/// -/// When talking about symbols, it's helpful to know a few things about where -/// symbols are located. Some symbols are located in the dynamic symbol table -/// of the executable which in theory means that they're available for dynamic -/// linking and lookup. Other symbols end up only in the local symbol table of -/// the file. This loosely corresponds to pub and priv functions in Rust. -/// -/// Armed with this knowledge, we know that our solution for address to symbol -/// translation will need to consult both the local and dynamic symbol tables. -/// With that in mind, here's our options of translating an address to -/// a symbol. -/// -/// * Use dladdr(). The original backtrace()-based idea actually uses dladdr() -/// behind the scenes to translate, and this is why backtrace() was not used. -/// Conveniently, this method works fantastically on macOS. It appears dladdr() -/// uses magic to consult the local symbol table, or we're putting everything -/// in the dynamic symbol table anyway. Regardless, for macOS, this is the -/// method used for translation. It's provided by the system and easy to do.o -/// -/// Sadly, all other systems have a dladdr() implementation that does not -/// consult the local symbol table. This means that most functions are blank -/// because they don't have symbols. This means that we need another solution. -/// -/// * Use unw_get_proc_name(). This is part of the libunwind api (not the -/// libgcc_s version of the libunwind api), but involves taking a dependency -/// to libunwind. We may pursue this route in the future if we bundle -/// libunwind, but libunwind was unwieldy enough that it was not chosen at -/// this time to provide this functionality. -/// -/// * Shell out to a utility like `readelf`. Crazy though it may sound, it's a -/// semi-reasonable solution. The stdlib already knows how to spawn processes, -/// so in theory it could invoke readelf, parse the output, and consult the -/// local/dynamic symbol tables from there. This ended up not getting chosen -/// due to the craziness of the idea plus the advent of the next option. -/// -/// * Use `libbacktrace`. It turns out that this is a small library bundled in -/// the gcc repository which provides backtrace and symbol translation -/// functionality. All we really need from it is the backtrace functionality, -/// and we only really need this on everything that's not macOS, so this is the -/// chosen route for now. -/// -/// In summary, the current situation uses libgcc_s to get a trace of stack -/// pointers, and we use dladdr() or libbacktrace to translate these addresses -/// 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. +/// See sys/unix/backtrace/mod.rs for an explanation of the method used here. pub use self::tracing::unwind_backtrace; pub use self::printing::{foreach_symbol_fileline, resolve_symname}; @@ -91,7 +18,6 @@ mod tracing; // symbol resolvers: mod printing; -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")))] pub mod gnu { use io; use fs; diff --git a/src/libstd/sys/redox/backtrace/tracing/mod.rs b/src/libstd/sys/redox/backtrace/printing.rs similarity index 60% rename from src/libstd/sys/redox/backtrace/tracing/mod.rs rename to src/libstd/sys/redox/backtrace/printing.rs index c9c8e260d2f..3e937dbe623 100644 --- a/src/libstd/sys/redox/backtrace/tracing/mod.rs +++ b/src/libstd/sys/redox/backtrace/printing.rs @@ -1,4 +1,4 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,11 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::imp::*; - -#[cfg(not(all(target_os = "ios", target_arch = "arm")))] -#[path = "gcc_s.rs"] -mod imp; -#[cfg(all(target_os = "ios", target_arch = "arm"))] -#[path = "backtrace_fn.rs"] -mod imp; +pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname}; diff --git a/src/libstd/sys/redox/backtrace/printing/dladdr.rs b/src/libstd/sys/redox/backtrace/printing/dladdr.rs deleted file mode 100644 index 05a071a7978..00000000000 --- a/src/libstd/sys/redox/backtrace/printing/dladdr.rs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014-2015 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 intrinsics; -use ffi::CStr; -use libc; -use sys::backtrace::BacktraceContext; -use sys_common::backtrace::Frame; - -pub fn resolve_symname(frame: Frame, - callback: F, - _: &BacktraceContext) -> io::Result<()> - where F: FnOnce(Option<&str>) -> io::Result<()> -{ - unsafe { - let mut info: Dl_info = intrinsics::init(); - let symname = if dladdr(frame.exact_position, &mut info) == 0 { - None - } else { - CStr::from_ptr(info.dli_sname).to_str().ok() - }; - callback(symname) - } -} - -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, - dli_fbase: *mut libc::c_void, - dli_sname: *const libc::c_char, - dli_saddr: *mut libc::c_void, -} - -extern { - fn dladdr(addr: *const libc::c_void, - info: *mut Dl_info) -> libc::c_int; -} diff --git a/src/libstd/sys/redox/backtrace/printing/mod.rs b/src/libstd/sys/redox/backtrace/printing/mod.rs deleted file mode 100644 index 1ae82e01100..00000000000 --- a/src/libstd/sys/redox/backtrace/printing/mod.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014-2015 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. - -pub use self::imp::{foreach_symbol_fileline, resolve_symname}; - -#[cfg(any(target_os = "macos", target_os = "ios", - target_os = "emscripten"))] -#[path = "dladdr.rs"] -mod imp; - -#[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}; -} diff --git a/src/libstd/sys/redox/backtrace/tracing/gcc_s.rs b/src/libstd/sys/redox/backtrace/tracing.rs similarity index 100% rename from src/libstd/sys/redox/backtrace/tracing/gcc_s.rs rename to src/libstd/sys/redox/backtrace/tracing.rs diff --git a/src/libstd/sys/redox/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/redox/backtrace/tracing/backtrace_fn.rs deleted file mode 100644 index ecd32aa9462..00000000000 --- a/src/libstd/sys/redox/backtrace/tracing/backtrace_fn.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014-2015 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. - -/// As always - iOS on arm uses SjLj exceptions and -/// _Unwind_Backtrace is even not available there. Still, -/// backtraces could be extracted using a backtrace function, -/// which thanks god is public -/// -/// As mentioned in a huge comment block in `super::super`, backtrace -/// doesn't play well with green threads, so while it is extremely nice and -/// simple to use it should be used only on iOS devices as the only viable -/// option. - -use io; -use libc; -use sys::backtrace::BacktraceContext; -use sys_common::backtrace::Frame; - -#[inline(never)] // if we know this is a function call, we can skip it when - // tracing -pub fn unwind_backtrace(frames: &mut [Frame]) - -> io::Result<(usize, BacktraceContext)> -{ - const FRAME_LEN: usize = 100; - assert!(FRAME_LEN >= frames.len()); - let mut raw_frames = [::ptr::null_mut(); FRAME_LEN]; - let nb_frames = unsafe { - backtrace(raw_frames.as_mut_ptr(), raw_frames.len() as libc::c_int) - } as usize; - for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) { - *to = Frame { - exact_position: *from, - symbol_addr: *from, - }; - } - Ok((nb_frames as usize, BacktraceContext)) -} - -extern { - fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int; -}