Skip to content

Commit f25c228

Browse files
committed
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`.
2 parents 82be83c + 9d67d5a commit f25c228

File tree

7 files changed

+197
-45
lines changed

7 files changed

+197
-45
lines changed

src/libbacktrace/config.sub

+35-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#! /bin/sh
22
# Configuration validation subroutine script.
3-
# Copyright 1992-2016 Free Software Foundation, Inc.
3+
# Copyright 1992-2017 Free Software Foundation, Inc.
44

5-
timestamp='2016-01-01'
5+
timestamp='2017-04-02'
66

77
# This file is free software; you can redistribute it and/or modify it
88
# 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>."
6767
version="\
6868
GNU config.sub ($timestamp)
6969
70-
Copyright 1992-2016 Free Software Foundation, Inc.
70+
Copyright 1992-2017 Free Software Foundation, Inc.
7171
7272
This is free software; see the source for copying conditions. There is NO
7373
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ case $maybe_os in
117117
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
118118
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
119119
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
120-
kopensolaris*-gnu* | \
120+
kopensolaris*-gnu* | cloudabi*-eabi* | \
121121
storm-chaos* | os2-emx* | rtmk-nova*)
122122
os=-$maybe_os
123123
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -263,7 +263,7 @@ case $basic_machine in
263263
| fido | fr30 | frv | ft32 \
264264
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
265265
| hexagon \
266-
| i370 | i860 | i960 | ia64 \
266+
| i370 | i860 | i960 | ia16 | ia64 \
267267
| ip2k | iq2000 \
268268
| k1om \
269269
| le32 | le64 \
@@ -301,6 +301,7 @@ case $basic_machine in
301301
| open8 | or1k | or1knd | or32 \
302302
| pdp10 | pdp11 | pj | pjl \
303303
| powerpc | powerpc64 | powerpc64le | powerpcle \
304+
| pru \
304305
| pyramid \
305306
| riscv32 | riscv64 \
306307
| rl78 | rx \
@@ -314,6 +315,7 @@ case $basic_machine in
314315
| ubicom32 \
315316
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
316317
| visium \
318+
| wasm32 \
317319
| we32k \
318320
| x86 | xc16x | xstormy16 | xtensa \
319321
| z8k | z80)
@@ -387,7 +389,7 @@ case $basic_machine in
387389
| h8300-* | h8500-* \
388390
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
389391
| hexagon-* \
390-
| i*86-* | i860-* | i960-* | ia64-* \
392+
| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
391393
| ip2k-* | iq2000-* \
392394
| k1om-* \
393395
| le32-* | le64-* \
@@ -428,6 +430,7 @@ case $basic_machine in
428430
| orion-* \
429431
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
430432
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
433+
| pru-* \
431434
| pyramid-* \
432435
| riscv32-* | riscv64-* \
433436
| rl78-* | romp-* | rs6000-* | rx-* \
@@ -444,6 +447,7 @@ case $basic_machine in
444447
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
445448
| vax-* \
446449
| visium-* \
450+
| wasm32-* \
447451
| we32k-* \
448452
| x86-* | x86_64-* | xc16x-* | xps100-* \
449453
| xstormy16-* | xtensa*-* \
@@ -643,6 +647,14 @@ case $basic_machine in
643647
basic_machine=m68k-bull
644648
os=-sysv3
645649
;;
650+
e500v[12])
651+
basic_machine=powerpc-unknown
652+
os=$os"spe"
653+
;;
654+
e500v[12]-*)
655+
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
656+
os=$os"spe"
657+
;;
646658
ebmon29k)
647659
basic_machine=a29k-amd
648660
os=-ebmon
@@ -938,6 +950,9 @@ case $basic_machine in
938950
nsr-tandem)
939951
basic_machine=nsr-tandem
940952
;;
953+
nsx-tandem)
954+
basic_machine=nsx-tandem
955+
;;
941956
op50n-* | op60c-*)
942957
basic_machine=hppa1.1-oki
943958
os=-proelf
@@ -1022,7 +1037,7 @@ case $basic_machine in
10221037
ppc-* | ppcbe-*)
10231038
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
10241039
;;
1025-
ppcle | powerpclittle | ppc-le | powerpc-little)
1040+
ppcle | powerpclittle)
10261041
basic_machine=powerpcle-unknown
10271042
;;
10281043
ppcle-* | powerpclittle-*)
@@ -1032,7 +1047,7 @@ case $basic_machine in
10321047
;;
10331048
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
10341049
;;
1035-
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
1050+
ppc64le | powerpc64little)
10361051
basic_machine=powerpc64le-unknown
10371052
;;
10381053
ppc64le-* | powerpc64little-*)
@@ -1233,6 +1248,9 @@ case $basic_machine in
12331248
basic_machine=a29k-wrs
12341249
os=-vxworks
12351250
;;
1251+
wasm32)
1252+
basic_machine=wasm32-unknown
1253+
;;
12361254
w65*)
12371255
basic_machine=w65-wdc
12381256
os=-none
@@ -1382,14 +1400,14 @@ case $os in
13821400
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
13831401
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
13841402
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
1385-
| -bitrig* | -openbsd* | -solidbsd* \
1403+
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
13861404
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
13871405
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
13881406
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
13891407
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
1390-
| -chorusos* | -chorusrdb* | -cegcc* \
1408+
| -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
13911409
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
1392-
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
1410+
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
13931411
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
13941412
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
13951413
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
@@ -1399,7 +1417,7 @@ case $os in
13991417
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
14001418
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
14011419
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
1402-
| -onefs* | -tirtos*)
1420+
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
14031421
# Remember, each alternative MUST END IN *, to match a version number.
14041422
;;
14051423
-qnx*)
@@ -1531,6 +1549,8 @@ case $os in
15311549
;;
15321550
-nacl*)
15331551
;;
1552+
-ios)
1553+
;;
15341554
-none)
15351555
;;
15361556
*)
@@ -1626,6 +1646,9 @@ case $basic_machine in
16261646
sparc-* | *-sun)
16271647
os=-sunos4.1.1
16281648
;;
1649+
pru-*)
1650+
os=-elf
1651+
;;
16291652
*-be)
16301653
os=-beos
16311654
;;

src/libstd/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn main() {
2121
let target = env::var("TARGET").expect("TARGET was not set");
2222
let host = env::var("HOST").expect("HOST was not set");
2323
if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") &&
24-
!target.contains("emscripten") && !target.contains("fuchsia") && !target.contains("redox") {
24+
!target.contains("emscripten") && !target.contains("fuchsia") {
2525
let _ = build_libbacktrace(&host, &target);
2626
}
2727

src/libstd/sys/redox/backtrace.rs

-32
This file was deleted.

src/libstd/sys/redox/backtrace/mod.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// See sys/unix/backtrace/mod.rs for an explanation of the method used here.
12+
13+
pub use self::tracing::unwind_backtrace;
14+
pub use self::printing::{foreach_symbol_fileline, resolve_symname};
15+
16+
// tracing impls:
17+
mod tracing;
18+
// symbol resolvers:
19+
mod printing;
20+
21+
pub mod gnu {
22+
use io;
23+
use fs;
24+
use libc::c_char;
25+
use vec::Vec;
26+
use ffi::OsStr;
27+
use os::unix::ffi::OsStrExt;
28+
use io::Read;
29+
30+
pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
31+
let mut exefile = fs::File::open("sys:exe")?;
32+
let mut exename = Vec::new();
33+
exefile.read_to_end(&mut exename)?;
34+
if exename.last() == Some(&b'\n') {
35+
exename.pop();
36+
}
37+
let file = fs::File::open(OsStr::from_bytes(&exename))?;
38+
Ok((exename.into_iter().map(|c| c as c_char).collect(), file))
39+
}
40+
}
41+
42+
pub struct BacktraceContext;
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use error::Error;
12+
use io;
13+
use libc;
14+
use sys::backtrace::BacktraceContext;
15+
use sys_common::backtrace::Frame;
16+
17+
use unwind as uw;
18+
19+
struct Context<'a> {
20+
idx: usize,
21+
frames: &'a mut [Frame],
22+
}
23+
24+
#[derive(Debug)]
25+
struct UnwindError(uw::_Unwind_Reason_Code);
26+
27+
impl Error for UnwindError {
28+
fn description(&self) -> &'static str {
29+
"unexpected return value while unwinding"
30+
}
31+
}
32+
33+
impl ::fmt::Display for UnwindError {
34+
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
35+
write!(f, "{}: {:?}", self.description(), self.0)
36+
}
37+
}
38+
39+
#[inline(never)] // if we know this is a function call, we can skip it when
40+
// tracing
41+
pub fn unwind_backtrace(frames: &mut [Frame])
42+
-> io::Result<(usize, BacktraceContext)>
43+
{
44+
let mut cx = Context {
45+
idx: 0,
46+
frames: frames,
47+
};
48+
let result_unwind = unsafe {
49+
uw::_Unwind_Backtrace(trace_fn,
50+
&mut cx as *mut Context
51+
as *mut libc::c_void)
52+
};
53+
// See libunwind:src/unwind/Backtrace.c for the return values.
54+
// No, there is no doc.
55+
match result_unwind {
56+
// These return codes seem to be benign and need to be ignored for backtraces
57+
// to show up properly on all tested platforms.
58+
uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
59+
Ok((cx.idx, BacktraceContext))
60+
}
61+
_ => {
62+
Err(io::Error::new(io::ErrorKind::Other,
63+
UnwindError(result_unwind)))
64+
}
65+
}
66+
}
67+
68+
extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
69+
arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
70+
let cx = unsafe { &mut *(arg as *mut Context) };
71+
let mut ip_before_insn = 0;
72+
let mut ip = unsafe {
73+
uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
74+
};
75+
if !ip.is_null() && ip_before_insn == 0 {
76+
// this is a non-signaling frame, so `ip` refers to the address
77+
// after the calling instruction. account for that.
78+
ip = (ip as usize - 1) as *mut _;
79+
}
80+
81+
// dladdr() on osx gets whiny when we use FindEnclosingFunction, and
82+
// it appears to work fine without it, so we only use
83+
// FindEnclosingFunction on non-osx platforms. In doing so, we get a
84+
// slightly more accurate stack trace in the process.
85+
//
86+
// This is often because panic involves the last instruction of a
87+
// function being "call std::rt::begin_unwind", with no ret
88+
// instructions after it. This means that the return instruction
89+
// pointer points *outside* of the calling function, and by
90+
// unwinding it we go back to the original function.
91+
let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
92+
ip
93+
} else {
94+
unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
95+
};
96+
97+
if cx.idx < cx.frames.len() {
98+
cx.frames[cx.idx] = Frame {
99+
symbol_addr: symaddr,
100+
exact_position: ip,
101+
};
102+
cx.idx += 1;
103+
}
104+
105+
uw::_URC_NO_REASON
106+
}

src/libunwind/build.rs

+2
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ fn main() {
4141
println!("cargo:rustc-link-lib=unwind");
4242
} else if target.contains("haiku") {
4343
println!("cargo:rustc-link-lib=gcc_s");
44+
} else if target.contains("redox") {
45+
println!("cargo:rustc-link-lib=gcc");
4446
}
4547
}

0 commit comments

Comments
 (0)