1
Fork 0

Make it possible to instantiate hardcoded Backtrace from test

This commit is contained in:
David Tolnay 2020-02-13 00:13:48 -08:00
parent 1f1ca877b7
commit a9cc010c48
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82

View file

@ -92,6 +92,7 @@
// a backtrace or actually symbolizing it. // a backtrace or actually symbolizing it.
use crate::env; use crate::env;
use crate::ffi::c_void;
use crate::fmt; use crate::fmt;
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use crate::sync::Mutex; use crate::sync::Mutex;
@ -144,10 +145,16 @@ fn _assert_send_sync() {
} }
struct BacktraceFrame { struct BacktraceFrame {
frame: backtrace::Frame, frame: RawFrame,
symbols: Vec<BacktraceSymbol>, symbols: Vec<BacktraceSymbol>,
} }
enum RawFrame {
Actual(backtrace::Frame),
#[cfg(test)]
Fake,
}
struct BacktraceSymbol { struct BacktraceSymbol {
name: Option<Vec<u8>>, name: Option<Vec<u8>>,
filename: Option<BytesOrWide>, filename: Option<BytesOrWide>,
@ -293,7 +300,10 @@ impl Backtrace {
let mut actual_start = None; let mut actual_start = None;
unsafe { unsafe {
backtrace::trace_unsynchronized(|frame| { backtrace::trace_unsynchronized(|frame| {
frames.push(BacktraceFrame { frame: frame.clone(), symbols: Vec::new() }); frames.push(BacktraceFrame {
frame: RawFrame::Actual(frame.clone()),
symbols: Vec::new(),
});
if frame.symbol_address() as usize == ip && actual_start.is_none() { if frame.symbol_address() as usize == ip && actual_start.is_none() {
actual_start = Some(frames.len()); actual_start = Some(frames.len());
} }
@ -393,8 +403,13 @@ impl Capture {
let _lock = lock(); let _lock = lock();
for frame in self.frames.iter_mut() { for frame in self.frames.iter_mut() {
let symbols = &mut frame.symbols; let symbols = &mut frame.symbols;
let frame = match &frame.frame {
RawFrame::Actual(frame) => frame,
#[cfg(test)]
RawFrame::Fake => unimplemented!(),
};
unsafe { unsafe {
backtrace::resolve_frame_unsynchronized(&frame.frame, |symbol| { backtrace::resolve_frame_unsynchronized(frame, |symbol| {
symbols.push(BacktraceSymbol { symbols.push(BacktraceSymbol {
name: symbol.name().map(|m| m.as_bytes().to_vec()), name: symbol.name().map(|m| m.as_bytes().to_vec()),
filename: symbol.filename_raw().map(|b| match b { filename: symbol.filename_raw().map(|b| match b {
@ -408,3 +423,13 @@ impl Capture {
} }
} }
} }
impl RawFrame {
fn ip(&self) -> *mut c_void {
match self {
RawFrame::Actual(frame) => frame.ip(),
#[cfg(test)]
RawFrame::Fake => 1 as *mut c_void,
}
}
}