]> git.proxmox.com Git - rustc.git/blob - vendor/backtrace/src/backtrace/mod.rs
New upstream version 1.32.0~beta.2+dfsg1
[rustc.git] / vendor / backtrace / src / backtrace / mod.rs
1 use std::fmt;
2
3 use std::os::raw::c_void;
4
5 /// Inspects the current call-stack, passing all active frames into the closure
6 /// provided to calculate a stack trace.
7 ///
8 /// This function is the workhorse of this library in calculating the stack
9 /// traces for a program. The given closure `cb` is yielded instances of a
10 /// `Frame` which represent information about that call frame on the stack. The
11 /// closure is yielded frames in a top-down fashion (most recently called
12 /// functions first).
13 ///
14 /// The closure's return value is an indication of whether the backtrace should
15 /// continue. A return value of `false` will terminate the backtrace and return
16 /// immediately.
17 ///
18 /// Once a `Frame` is acquired you will likely want to call `backtrace::resolve`
19 /// to convert the `ip` (instruction pointer) or symbol address to a `Symbol`
20 /// through which the name and/or filename/line number can be learned.
21 ///
22 /// Note that this is a relatively low-level function and if you'd like to, for
23 /// example, capture a backtrace to be inspected later, then the `Backtrace`
24 /// type may be more appropriate.
25 ///
26 /// # Example
27 ///
28 /// ```
29 /// extern crate backtrace;
30 ///
31 /// fn main() {
32 /// backtrace::trace(|frame| {
33 /// // ...
34 ///
35 /// true // continue the backtrace
36 /// });
37 /// }
38 /// ```
39 #[inline(never)] // if this is never inlined then the first frame can be known
40 // to be skipped
41 pub fn trace<F: FnMut(&Frame) -> bool>(mut cb: F) {
42 trace_imp(&mut cb)
43 }
44
45 /// A trait representing one frame of a backtrace, yielded to the `trace`
46 /// function of this crate.
47 ///
48 /// The tracing function's closure will be yielded frames, and the frame is
49 /// virtually dispatched as the underlying implementation is not always known
50 /// until runtime.
51 pub struct Frame {
52 inner: FrameImp,
53 }
54
55 impl Frame {
56 /// Returns the current instruction pointer of this frame.
57 ///
58 /// This is normally the next instruction to execute in the frame, but not
59 /// all implementations list this with 100% accuracy (but it's generally
60 /// pretty close).
61 ///
62 /// It is recommended to pass this value to `backtrace::resolve` to turn it
63 /// into a symbol name.
64 pub fn ip(&self) -> *mut c_void {
65 self.inner.ip()
66 }
67
68 /// Returns the starting symbol address of the frame of this function.
69 ///
70 /// This will attempt to rewind the instruction pointer returned by `ip` to
71 /// the start of the function, returning that value. In some cases, however,
72 /// backends will just return `ip` from this function.
73 ///
74 /// The returned value can sometimes be used if `backtrace::resolve` failed
75 /// on the `ip` given above.
76 pub fn symbol_address(&self) -> *mut c_void {
77 self.inner.symbol_address()
78 }
79 }
80
81 impl fmt::Debug for Frame {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 f.debug_struct("Frame")
84 .field("ip", &self.ip())
85 .field("symbol_address", &self.symbol_address())
86 .finish()
87 }
88 }
89
90 cfg_if! {
91 if #[cfg(all(unix,
92 not(target_os = "emscripten"),
93 not(all(target_os = "ios", target_arch = "arm")),
94 feature = "libunwind"))] {
95 mod libunwind;
96 use self::libunwind::trace as trace_imp;
97 use self::libunwind::Frame as FrameImp;
98 } else if #[cfg(all(unix,
99 not(target_os = "emscripten"),
100 feature = "unix-backtrace"))] {
101 mod unix_backtrace;
102 use self::unix_backtrace::trace as trace_imp;
103 use self::unix_backtrace::Frame as FrameImp;
104 } else if #[cfg(all(windows, feature = "dbghelp"))] {
105 mod dbghelp;
106 use self::dbghelp::trace as trace_imp;
107 use self::dbghelp::Frame as FrameImp;
108 } else {
109 mod noop;
110 use self::noop::trace as trace_imp;
111 use self::noop::Frame as FrameImp;
112 }
113 }