#[cfg(all(not(backtrace), feature = "backtrace"))] mod capture { use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName}; use core::cell::UnsafeCell; use core::fmt::{self, Debug, Display}; use core::sync::atomic::{AtomicUsize, Ordering}; use std::borrow::Cow; use std::env; use std::path::{self, Path, PathBuf}; use std::sync::Once;
impl Backtrace { fn enabled() -> bool { static ENABLED: AtomicUsize = AtomicUsize::new(0); match ENABLED.load(Ordering::Relaxed) { 0 => {} 1 => returnfalse,
_ => returntrue,
} let enabled = match env::var_os("RUST_LIB_BACKTRACE") {
Some(s) => s != "0",
None => match env::var_os("RUST_BACKTRACE") {
Some(s) => s != "0",
None => false,
},
};
ENABLED.store(enabled as usize + 1, Ordering::Relaxed);
enabled
}
#[inline(never)] // want to make sure there's a frame here to remove pub(crate) fn capture() -> Backtrace { if Backtrace::enabled() {
Backtrace::create(Backtrace::capture as usize)
} else { let inner = Inner::Disabled;
Backtrace { inner }
}
}
// Capture a backtrace which starts just before the function addressed // by `ip` fn create(ip: usize) -> Backtrace { letmut frames = Vec::new(); letmut actual_start = None;
backtrace::trace(|frame| {
frames.push(BacktraceFrame {
frame: frame.clone(),
symbols: Vec::new(),
}); if frame.symbol_address() as usize == ip && actual_start.is_none() {
actual_start = Some(frames.len() + 1);
} true
});
// If no frames came out assume that this is an unsupported platform // since `backtrace` doesn't provide a way of learning this right // now, and this should be a good enough approximation. let inner = if frames.is_empty() {
Inner::Unsupported
} else {
Inner::Captured(LazilyResolvedCapture::new(Capture {
actual_start: actual_start.unwrap_or(0),
frames,
resolved: false,
}))
};
let full = fmt.alternate(); let (frames, style) = if full {
(&capture.frames[..], PrintFmt::Full)
} else {
(&capture.frames[capture.actual_start..], PrintFmt::Short)
};
// When printing paths we try to strip the cwd if it exists, // otherwise we just print the path as-is. Note that we also only do // this for the short format, because if it's full we presumably // want to print everything. let cwd = env::current_dir(); letmut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| {
output_filename(fmt, path, style, cwd.as_ref().ok())
};
letmut f = BacktraceFmt::new(fmt, style, &mut print_path);
f.add_context()?; for frame in frames { letmut f = f.frame(); if frame.symbols.is_empty() {
f.print_raw(frame.frame.ip(), None, None, None)?;
} else { for symbol in frame.symbols.iter() {
f.print_raw_with_column(
frame.frame.ip(),
symbol.name.as_ref().map(|b| SymbolName::new(b)),
symbol.filename.as_ref().map(|b| match b {
BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
}),
symbol.lineno,
symbol.colno,
)?;
}
}
}
f.finish()?;
Ok(())
}
}
fn force(&self) -> &Capture { self.sync.call_once(|| { // Safety: This exclusive reference can't overlap with any // others. `Once` guarantees callers will block until this // closure returns. `Once` also guarantees only a single caller // will enter this closure. unsafe { &mut *self.capture.get() }.resolve();
});
// Safety: This shared reference can't overlap with the exclusive // reference above. unsafe { &*self.capture.get() }
}
}
// Safety: Access to the inner value is synchronized using a thread-safe // `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too unsafeimpl Sync for LazilyResolvedCapture where Capture: Sync {}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.