summaryrefslogtreecommitdiffstats
path: root/vendor/backtrace/src/backtrace/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/backtrace/src/backtrace/mod.rs')
-rw-r--r--vendor/backtrace/src/backtrace/mod.rs162
1 files changed, 162 insertions, 0 deletions
diff --git a/vendor/backtrace/src/backtrace/mod.rs b/vendor/backtrace/src/backtrace/mod.rs
new file mode 100644
index 000000000..93355d744
--- /dev/null
+++ b/vendor/backtrace/src/backtrace/mod.rs
@@ -0,0 +1,162 @@
+use core::ffi::c_void;
+use core::fmt;
+
+/// Inspects the current call-stack, passing all active frames into the closure
+/// provided to calculate a stack trace.
+///
+/// This function is the workhorse of this library in calculating the stack
+/// traces for a program. The given closure `cb` is yielded instances of a
+/// `Frame` which represent information about that call frame on the stack. The
+/// closure is yielded frames in a top-down fashion (most recently called
+/// functions first).
+///
+/// The closure's return value is an indication of whether the backtrace should
+/// continue. A return value of `false` will terminate the backtrace and return
+/// immediately.
+///
+/// Once a `Frame` is acquired you will likely want to call `backtrace::resolve`
+/// to convert the `ip` (instruction pointer) or symbol address to a `Symbol`
+/// through which the name and/or filename/line number can be learned.
+///
+/// Note that this is a relatively low-level function and if you'd like to, for
+/// example, capture a backtrace to be inspected later, then the `Backtrace`
+/// type may be more appropriate.
+///
+/// # Required features
+///
+/// This function requires the `std` feature of the `backtrace` crate to be
+/// enabled, and the `std` feature is enabled by default.
+///
+/// # Panics
+///
+/// This function strives to never panic, but if the `cb` provided panics then
+/// some platforms will force a double panic to abort the process. Some
+/// platforms use a C library which internally uses callbacks which cannot be
+/// unwound through, so panicking from `cb` may trigger a process abort.
+///
+/// # Example
+///
+/// ```
+/// extern crate backtrace;
+///
+/// fn main() {
+/// backtrace::trace(|frame| {
+/// // ...
+///
+/// true // continue the backtrace
+/// });
+/// }
+/// ```
+#[cfg(feature = "std")]
+pub fn trace<F: FnMut(&Frame) -> bool>(cb: F) {
+ let _guard = crate::lock::lock();
+ unsafe { trace_unsynchronized(cb) }
+}
+
+/// Same as `trace`, only unsafe as it's unsynchronized.
+///
+/// This function does not have synchronization guarantees but is available
+/// when the `std` feature of this crate isn't compiled in. See the `trace`
+/// function for more documentation and examples.
+///
+/// # Panics
+///
+/// See information on `trace` for caveats on `cb` panicking.
+pub unsafe fn trace_unsynchronized<F: FnMut(&Frame) -> bool>(mut cb: F) {
+ trace_imp(&mut cb)
+}
+
+/// A trait representing one frame of a backtrace, yielded to the `trace`
+/// function of this crate.
+///
+/// The tracing function's closure will be yielded frames, and the frame is
+/// virtually dispatched as the underlying implementation is not always known
+/// until runtime.
+#[derive(Clone)]
+pub struct Frame {
+ pub(crate) inner: FrameImp,
+}
+
+impl Frame {
+ /// Returns the current instruction pointer of this frame.
+ ///
+ /// This is normally the next instruction to execute in the frame, but not
+ /// all implementations list this with 100% accuracy (but it's generally
+ /// pretty close).
+ ///
+ /// It is recommended to pass this value to `backtrace::resolve` to turn it
+ /// into a symbol name.
+ pub fn ip(&self) -> *mut c_void {
+ self.inner.ip()
+ }
+
+ /// Returns the current stack pointer of this frame.
+ ///
+ /// In the case that a backend cannot recover the stack pointer for this
+ /// frame, a null pointer is returned.
+ pub fn sp(&self) -> *mut c_void {
+ self.inner.sp()
+ }
+
+ /// Returns the starting symbol address of the frame of this function.
+ ///
+ /// This will attempt to rewind the instruction pointer returned by `ip` to
+ /// the start of the function, returning that value. In some cases, however,
+ /// backends will just return `ip` from this function.
+ ///
+ /// The returned value can sometimes be used if `backtrace::resolve` failed
+ /// on the `ip` given above.
+ pub fn symbol_address(&self) -> *mut c_void {
+ self.inner.symbol_address()
+ }
+
+ /// Returns the base address of the module to which the frame belongs.
+ pub fn module_base_address(&self) -> Option<*mut c_void> {
+ self.inner.module_base_address()
+ }
+}
+
+impl fmt::Debug for Frame {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Frame")
+ .field("ip", &self.ip())
+ .field("symbol_address", &self.symbol_address())
+ .finish()
+ }
+}
+
+cfg_if::cfg_if! {
+ // This needs to come first, to ensure that
+ // Miri takes priority over the host platform
+ if #[cfg(miri)] {
+ pub(crate) mod miri;
+ use self::miri::trace as trace_imp;
+ pub(crate) use self::miri::Frame as FrameImp;
+ } else if #[cfg(
+ any(
+ all(
+ unix,
+ not(target_os = "emscripten"),
+ not(all(target_os = "ios", target_arch = "arm")),
+ ),
+ all(
+ target_env = "sgx",
+ target_vendor = "fortanix",
+ ),
+ )
+ )] {
+ mod libunwind;
+ use self::libunwind::trace as trace_imp;
+ pub(crate) use self::libunwind::Frame as FrameImp;
+ } else if #[cfg(all(windows, not(target_vendor = "uwp")))] {
+ mod dbghelp;
+ use self::dbghelp::trace as trace_imp;
+ pub(crate) use self::dbghelp::Frame as FrameImp;
+ #[cfg(target_env = "msvc")] // only used in dbghelp symbolize
+ pub(crate) use self::dbghelp::StackFrame;
+ } else {
+ mod noop;
+ use self::noop::trace as trace_imp;
+ pub(crate) use self::noop::Frame as FrameImp;
+ }
+}