#![doc(html_root_url = "http://alexcrichton.com/backtrace-rs")]
#![deny(missing_docs)]
#![deny(warnings)]
extern crate libc;
#[cfg(feature = "kernel32-sys")] extern crate kernel32;
#[cfg(feature = "winapi")] extern crate winapi;
#[cfg(feature = "dbghelp")] extern crate dbghelp;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize;
#[macro_use]
extern crate cfg_if;
extern crate rustc_demangle;
#[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 {
include!(concat!(env!("OUT_DIR"), "/capture.rs"));
}
#[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;
}
}