#![doc(html_root_url = "http://alexcrichton.com/backtrace-rs")]
#![deny(missing_docs)]
#![deny(warnings)]
#[cfg(unix)]
extern crate libc;
#[cfg(all(windows, feature = "kernel32-sys"))] extern crate kernel32;
#[cfg(all(windows, feature = "winapi"))] extern crate winapi;
#[cfg(all(windows, feature = "dbghelp"))] extern crate dbghelp;
#[cfg(feature = "serde_derive")]
#[cfg_attr(feature = "serde_derive", macro_use)]
extern crate serde_derive;
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize;
#[macro_use]
extern crate cfg_if;
extern crate rustc_demangle;
#[cfg(feature = "cpp_demangle")]
extern crate cpp_demangle;
#[cfg(all(feature = "gimli-symbolize",
unix,
target_os = "linux"))]
extern crate addr2line;
#[cfg(all(feature = "gimli-symbolize",
unix,
target_os = "linux"))]
extern crate findshlibs;
#[allow(dead_code)] #[cfg(unix)]
#[macro_use]
mod dylib;
pub use backtrace::{trace, Frame};
mod backtrace;
pub use symbolize::{resolve, Symbol, SymbolName};
mod symbolize;
pub use capture::{Backtrace, BacktraceFrame, BacktraceSymbol};
mod capture;
#[allow(dead_code)]
struct Bomb {
enabled: bool,
}
#[allow(dead_code)]
impl Drop for Bomb {
fn drop(&mut self) {
if self.enabled {
panic!("cannot panic during the backtrace function");
}
}
}
#[allow(dead_code)]
mod lock {
use std::cell::Cell;
use std::mem;
use std::sync::{Once, Mutex, MutexGuard, ONCE_INIT};
pub struct LockGuard(MutexGuard<'static, ()>);
static mut LOCK: *mut Mutex<()> = 0 as *mut _;
static INIT: Once = ONCE_INIT;
thread_local!(static LOCK_HELD: Cell<bool> = Cell::new(false));
impl Drop for LockGuard {
fn drop(&mut self) {
LOCK_HELD.with(|slot| {
assert!(slot.get());
slot.set(false);
});
}
}
pub fn lock() -> Option<LockGuard> {
if LOCK_HELD.with(|l| l.get()) {
return None
}
LOCK_HELD.with(|s| s.set(true));
unsafe {
INIT.call_once(|| {
LOCK = mem::transmute(Box::new(Mutex::new(())));
});
Some(LockGuard((*LOCK).lock().unwrap()))
}
}
}
#[cfg(all(windows, feature = "dbghelp"))]
unsafe fn dbghelp_init() {
static mut INITIALIZED: bool = false;
if !INITIALIZED {
dbghelp::SymInitializeW(kernel32::GetCurrentProcess(),
0 as *mut _,
winapi::TRUE);
INITIALIZED = true;
}
}