]> git.proxmox.com Git - rustc.git/blame - vendor/backtrace/src/lib.rs
New upstream version 1.43.0+dfsg1
[rustc.git] / vendor / backtrace / src / lib.rs
CommitLineData
7cac9316
XL
1//! A library for acquiring a backtrace at runtime
2//!
3//! This library is meant to supplement the `RUST_BACKTRACE=1` support of the
4//! standard library by allowing an acquisition of a backtrace at runtime
5//! programmatically. The backtraces generated by this library do not need to be
6//! parsed, for example, and expose the functionality of multiple backend
7//! implementations.
8//!
9//! # Implementation
10//!
11//! This library makes use of a number of strategies for actually acquiring a
12//! backtrace. For example unix uses libgcc's libunwind bindings by default to
13//! acquire a backtrace, but coresymbolication or dladdr is used on OSX to
14//! acquire symbol names while linux uses gcc's libbacktrace.
15//!
16//! When using the default feature set of this library the "most reasonable" set
17//! of defaults is chosen for the current platform, but the features activated
18//! can also be controlled at a finer granularity.
19//!
7cac9316
XL
20//! # API Principles
21//!
ea8adc8c 22//! This library attempts to be as flexible as possible to accommodate different
7cac9316
XL
23//! backend implementations of acquiring a backtrace. Consequently the currently
24//! exported functions are closure-based as opposed to the likely expected
25//! iterator-based versions. This is done due to limitations of the underlying
26//! APIs used from the system.
27//!
28//! # Usage
29//!
30//! First, add this to your Cargo.toml
31//!
32//! ```toml
33//! [dependencies]
dc9dc135 34//! backtrace = "0.3"
7cac9316
XL
35//! ```
36//!
37//! Next:
38//!
39//! ```
40//! extern crate backtrace;
41//!
42//! fn main() {
0731742a
XL
43//! # // Unsafe here so test passes on no_std.
44//! # #[cfg(feature = "std")] {
7cac9316
XL
45//! backtrace::trace(|frame| {
46//! let ip = frame.ip();
47//! let symbol_address = frame.symbol_address();
48//!
49//! // Resolve this instruction pointer to a symbol name
dc9dc135 50//! backtrace::resolve_frame(frame, |symbol| {
7cac9316
XL
51//! if let Some(name) = symbol.name() {
52//! // ...
53//! }
54//! if let Some(filename) = symbol.filename() {
55//! // ...
56//! }
57//! });
58//!
59//! true // keep going to the next frame
60//! });
61//! }
0731742a 62//! # }
7cac9316
XL
63//! ```
64
8faf50e0 65#![doc(html_root_url = "https://docs.rs/backtrace")]
7cac9316 66#![deny(missing_docs)]
0731742a 67#![no_std]
74b04a01
XL
68#![cfg_attr(
69 all(feature = "std", target_env = "sgx", target_vendor = "fortanix"),
70 feature(sgx_platform)
71)]
dc9dc135 72#![allow(bare_trait_objects)] // TODO: remove when updating to 2018 edition
416331ca 73#![allow(rust_2018_idioms)] // TODO: remove when updating to 2018 edition
0731742a
XL
74
75#[cfg(feature = "std")]
dc9dc135
XL
76#[macro_use]
77extern crate std;
7cac9316 78
416331ca 79pub use crate::backtrace::{trace_unsynchronized, Frame};
7cac9316
XL
80mod backtrace;
81
416331ca
XL
82pub use crate::symbolize::resolve_frame_unsynchronized;
83pub use crate::symbolize::{resolve_unsynchronized, Symbol, SymbolName};
7cac9316
XL
84mod symbolize;
85
416331ca 86pub use crate::types::BytesOrWideString;
0731742a
XL
87mod types;
88
416331ca
XL
89#[cfg(feature = "std")]
90pub use crate::symbolize::clear_symbol_cache;
91
e1599b0c
XL
92mod print;
93pub use print::{BacktraceFmt, BacktraceFrameFmt, PrintFmt};
94
416331ca 95cfg_if::cfg_if! {
0731742a 96 if #[cfg(feature = "std")] {
416331ca
XL
97 pub use crate::backtrace::trace;
98 pub use crate::symbolize::{resolve, resolve_frame};
99 pub use crate::capture::{Backtrace, BacktraceFrame, BacktraceSymbol};
0731742a
XL
100 mod capture;
101 }
102}
7cac9316
XL
103
104#[allow(dead_code)]
105struct Bomb {
106 enabled: bool,
107}
108
109#[allow(dead_code)]
110impl Drop for Bomb {
111 fn drop(&mut self) {
112 if self.enabled {
113 panic!("cannot panic during the backtrace function");
114 }
115 }
116}
117
118#[allow(dead_code)]
0731742a 119#[cfg(feature = "std")]
7cac9316 120mod lock {
0731742a 121 use std::boxed::Box;
dc9dc135 122 use std::cell::Cell;
416331ca 123 use std::sync::{Mutex, MutexGuard, Once};
7cac9316 124
dc9dc135 125 pub struct LockGuard(Option<MutexGuard<'static, ()>>);
7cac9316
XL
126
127 static mut LOCK: *mut Mutex<()> = 0 as *mut _;
416331ca 128 static INIT: Once = Once::new();
7cac9316
XL
129 thread_local!(static LOCK_HELD: Cell<bool> = Cell::new(false));
130
131 impl Drop for LockGuard {
132 fn drop(&mut self) {
dc9dc135
XL
133 if self.0.is_some() {
134 LOCK_HELD.with(|slot| {
135 assert!(slot.get());
136 slot.set(false);
137 });
138 }
7cac9316
XL
139 }
140 }
141
dc9dc135 142 pub fn lock() -> LockGuard {
7cac9316 143 if LOCK_HELD.with(|l| l.get()) {
dc9dc135 144 return LockGuard(None);
7cac9316
XL
145 }
146 LOCK_HELD.with(|s| s.set(true));
147 unsafe {
148 INIT.call_once(|| {
0731742a 149 LOCK = Box::into_raw(Box::new(Mutex::new(())));
7cac9316 150 });
dc9dc135 151 LockGuard(Some((*LOCK).lock().unwrap()))
7cac9316
XL
152 }
153 }
154}
155
416331ca 156#[cfg(all(windows, feature = "dbghelp", not(target_vendor = "uwp")))]
dc9dc135
XL
157mod dbghelp;
158#[cfg(windows)]
159mod windows;