Auto merge of #43635 - ids1024:backtrace-redox, r=alexcrichton
Make backtraces work on Redox, copying Unix implementation The `backtrace/` directory here is the same as the Unix one, except for adding an implementation of `get_executable_filename`.
This commit is contained in:
commit
f25c2283b3
7 changed files with 197 additions and 45 deletions
47
src/libbacktrace/config.sub
vendored
47
src/libbacktrace/config.sub
vendored
|
|
@ -1,8 +1,8 @@
|
|||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2016-01-01'
|
||||
timestamp='2017-04-02'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
|
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
|
@ -117,7 +117,7 @@ case $maybe_os in
|
|||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||
kopensolaris*-gnu* | \
|
||||
kopensolaris*-gnu* | cloudabi*-eabi* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
|
|
@ -263,7 +263,7 @@ case $basic_machine in
|
|||
| fido | fr30 | frv | ft32 \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| i370 | i860 | i960 | ia16 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| k1om \
|
||||
| le32 | le64 \
|
||||
|
|
@ -301,6 +301,7 @@ case $basic_machine in
|
|||
| open8 | or1k | or1knd | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| pru \
|
||||
| pyramid \
|
||||
| riscv32 | riscv64 \
|
||||
| rl78 | rx \
|
||||
|
|
@ -314,6 +315,7 @@ case $basic_machine in
|
|||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| visium \
|
||||
| wasm32 \
|
||||
| we32k \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
|
|
@ -387,7 +389,7 @@ case $basic_machine in
|
|||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| k1om-* \
|
||||
| le32-* | le64-* \
|
||||
|
|
@ -428,6 +430,7 @@ case $basic_machine in
|
|||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| pru-* \
|
||||
| pyramid-* \
|
||||
| riscv32-* | riscv64-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
|
|
@ -444,6 +447,7 @@ case $basic_machine in
|
|||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| visium-* \
|
||||
| wasm32-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
|
|
@ -643,6 +647,14 @@ case $basic_machine in
|
|||
basic_machine=m68k-bull
|
||||
os=-sysv3
|
||||
;;
|
||||
e500v[12])
|
||||
basic_machine=powerpc-unknown
|
||||
os=$os"spe"
|
||||
;;
|
||||
e500v[12]-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=$os"spe"
|
||||
;;
|
||||
ebmon29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-ebmon
|
||||
|
|
@ -938,6 +950,9 @@ case $basic_machine in
|
|||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
nsx-tandem)
|
||||
basic_machine=nsx-tandem
|
||||
;;
|
||||
op50n-* | op60c-*)
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
|
|
@ -1022,7 +1037,7 @@ case $basic_machine in
|
|||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
ppcle | powerpclittle)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
|
|
@ -1032,7 +1047,7 @@ case $basic_machine in
|
|||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
ppc64le | powerpc64little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
|
|
@ -1233,6 +1248,9 @@ case $basic_machine in
|
|||
basic_machine=a29k-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
wasm32)
|
||||
basic_machine=wasm32-unknown
|
||||
;;
|
||||
w65*)
|
||||
basic_machine=w65-wdc
|
||||
os=-none
|
||||
|
|
@ -1382,14 +1400,14 @@ case $os in
|
|||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
|
|
@ -1399,7 +1417,7 @@ case $os in
|
|||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
||||
| -onefs* | -tirtos*)
|
||||
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
|
|
@ -1531,6 +1549,8 @@ case $os in
|
|||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-ios)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
|
|
@ -1626,6 +1646,9 @@ case $basic_machine in
|
|||
sparc-* | *-sun)
|
||||
os=-sunos4.1.1
|
||||
;;
|
||||
pru-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ 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") &&
|
||||
!target.contains("emscripten") && !target.contains("fuchsia") && !target.contains("redox") {
|
||||
!target.contains("emscripten") && !target.contains("fuchsia") {
|
||||
let _ = build_libbacktrace(&host, &target);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright 2016 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use io;
|
||||
use sys_common::backtrace::Frame;
|
||||
|
||||
pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
|
||||
pub struct BacktraceContext;
|
||||
|
||||
#[inline(never)]
|
||||
pub fn unwind_backtrace(_frames: &mut [Frame])
|
||||
-> io::Result<(usize, BacktraceContext)>
|
||||
{
|
||||
Ok((0, BacktraceContext))
|
||||
}
|
||||
|
||||
pub mod gnu {
|
||||
use io;
|
||||
use fs;
|
||||
use libc::c_char;
|
||||
|
||||
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
|
||||
}
|
||||
}
|
||||
42
src/libstd/sys/redox/backtrace/mod.rs
Normal file
42
src/libstd/sys/redox/backtrace/mod.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// 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};
|
||||
|
||||
// tracing impls:
|
||||
mod tracing;
|
||||
// symbol resolvers:
|
||||
mod printing;
|
||||
|
||||
pub mod gnu {
|
||||
use io;
|
||||
use fs;
|
||||
use libc::c_char;
|
||||
use vec::Vec;
|
||||
use ffi::OsStr;
|
||||
use os::unix::ffi::OsStrExt;
|
||||
use io::Read;
|
||||
|
||||
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
|
||||
let mut exefile = fs::File::open("sys:exe")?;
|
||||
let mut exename = Vec::new();
|
||||
exefile.read_to_end(&mut exename)?;
|
||||
if exename.last() == Some(&b'\n') {
|
||||
exename.pop();
|
||||
}
|
||||
let file = fs::File::open(OsStr::from_bytes(&exename))?;
|
||||
Ok((exename.into_iter().map(|c| c as c_char).collect(), file))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BacktraceContext;
|
||||
11
src/libstd/sys/redox/backtrace/printing.rs
Normal file
11
src/libstd/sys/redox/backtrace/printing.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
|
||||
106
src/libstd/sys/redox/backtrace/tracing.rs
Normal file
106
src/libstd/sys/redox/backtrace/tracing.rs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use error::Error;
|
||||
use io;
|
||||
use libc;
|
||||
use sys::backtrace::BacktraceContext;
|
||||
use sys_common::backtrace::Frame;
|
||||
|
||||
use unwind as uw;
|
||||
|
||||
struct Context<'a> {
|
||||
idx: usize,
|
||||
frames: &'a mut [Frame],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct UnwindError(uw::_Unwind_Reason_Code);
|
||||
|
||||
impl Error for UnwindError {
|
||||
fn description(&self) -> &'static str {
|
||||
"unexpected return value while unwinding"
|
||||
}
|
||||
}
|
||||
|
||||
impl ::fmt::Display for UnwindError {
|
||||
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
|
||||
write!(f, "{}: {:?}", self.description(), self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[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)>
|
||||
{
|
||||
let mut cx = Context {
|
||||
idx: 0,
|
||||
frames: frames,
|
||||
};
|
||||
let result_unwind = unsafe {
|
||||
uw::_Unwind_Backtrace(trace_fn,
|
||||
&mut cx as *mut Context
|
||||
as *mut libc::c_void)
|
||||
};
|
||||
// See libunwind:src/unwind/Backtrace.c for the return values.
|
||||
// No, there is no doc.
|
||||
match result_unwind {
|
||||
// These return codes seem to be benign and need to be ignored for backtraces
|
||||
// to show up properly on all tested platforms.
|
||||
uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
|
||||
Ok((cx.idx, BacktraceContext))
|
||||
}
|
||||
_ => {
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
UnwindError(result_unwind)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
|
||||
arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
|
||||
let cx = unsafe { &mut *(arg as *mut Context) };
|
||||
let mut ip_before_insn = 0;
|
||||
let mut ip = unsafe {
|
||||
uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
|
||||
};
|
||||
if !ip.is_null() && ip_before_insn == 0 {
|
||||
// this is a non-signaling frame, so `ip` refers to the address
|
||||
// after the calling instruction. account for that.
|
||||
ip = (ip as usize - 1) as *mut _;
|
||||
}
|
||||
|
||||
// dladdr() on osx gets whiny when we use FindEnclosingFunction, and
|
||||
// it appears to work fine without it, so we only use
|
||||
// FindEnclosingFunction on non-osx platforms. In doing so, we get a
|
||||
// slightly more accurate stack trace in the process.
|
||||
//
|
||||
// This is often because panic involves the last instruction of a
|
||||
// function being "call std::rt::begin_unwind", with no ret
|
||||
// instructions after it. This means that the return instruction
|
||||
// pointer points *outside* of the calling function, and by
|
||||
// unwinding it we go back to the original function.
|
||||
let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
|
||||
ip
|
||||
} else {
|
||||
unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
|
||||
};
|
||||
|
||||
if cx.idx < cx.frames.len() {
|
||||
cx.frames[cx.idx] = Frame {
|
||||
symbol_addr: symaddr,
|
||||
exact_position: ip,
|
||||
};
|
||||
cx.idx += 1;
|
||||
}
|
||||
|
||||
uw::_URC_NO_REASON
|
||||
}
|
||||
|
|
@ -41,5 +41,7 @@ fn main() {
|
|||
println!("cargo:rustc-link-lib=unwind");
|
||||
} else if target.contains("haiku") {
|
||||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("redox") {
|
||||
println!("cargo:rustc-link-lib=gcc");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue