-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Companion to rust-lang/miri#1559
- Loading branch information
Showing
4 changed files
with
140 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
use std::ffi::c_void; | ||
use std::string::String; | ||
use std::vec::Vec; | ||
use std::boxed::Box; | ||
|
||
extern "Rust" { | ||
fn miri_get_backtrace() -> Box<[*mut ()]>; | ||
fn miri_resolve_frame(version: u8, ptr: *mut ()) -> MiriFrame; | ||
} | ||
|
||
#[derive(Debug)] | ||
struct MiriData { | ||
frames: Vec<*mut c_void> | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct MiriFrame { | ||
pub name: Box<[u8]>, | ||
pub filename: Box<[u8]>, | ||
pub lineno: u32, | ||
pub colno: u32, | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct Frame { | ||
pub addr: *mut c_void, | ||
pub inner: MiriFrame | ||
} | ||
|
||
// Miri is single threaded, and the raw | ||
// pointer isn't really a pointer (it's a magic value | ||
// returned by Miri) | ||
unsafe impl Send for Frame {} | ||
unsafe impl Sync for Frame {} | ||
|
||
impl Frame { | ||
pub fn ip(&self) -> *mut c_void { | ||
self.addr | ||
} | ||
|
||
pub fn sp(&self) -> *mut c_void { | ||
std::ptr::null_mut() | ||
} | ||
|
||
pub fn symbol_address(&self) -> *mut c_void { | ||
self.addr | ||
} | ||
|
||
pub fn module_base_address(&self) -> Option<*mut c_void> { | ||
None | ||
} | ||
} | ||
|
||
pub fn trace<F: FnMut(&super::Frame) -> bool>(cb: F) { | ||
// Miri is single threaded | ||
unsafe { trace_unsynchronized(cb) }; | ||
} | ||
|
||
|
||
pub fn resolve_addr(ptr: *mut c_void) -> Frame { | ||
let frame: MiriFrame = unsafe { miri_resolve_frame(0, ptr as *mut ()) }; | ||
Frame { | ||
addr: ptr, | ||
inner: frame | ||
} | ||
} | ||
|
||
pub unsafe fn trace_unsynchronized<F: FnMut(&super::Frame) -> bool>(mut cb: F) { | ||
let frames = miri_get_backtrace(); | ||
for ptr in frames.iter() { | ||
let frame = resolve_addr(*ptr as *mut c_void); | ||
cb(&super::Frame { | ||
inner: frame | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use core::marker::PhantomData; | ||
use core::ffi::c_void; | ||
|
||
use crate::symbolize::{ResolveWhat, SymbolName}; | ||
use crate::backtrace::miri::{resolve_addr, Frame}; | ||
use crate::types::BytesOrWideString; | ||
|
||
|
||
pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) { | ||
let sym = match what { | ||
ResolveWhat::Address(addr) => Symbol { | ||
inner: resolve_addr(addr), | ||
_unused: PhantomData | ||
}, | ||
ResolveWhat::Frame(frame) => { | ||
Symbol { | ||
inner: frame.inner.clone(), | ||
_unused: PhantomData | ||
} | ||
} | ||
}; | ||
cb(&super::Symbol { inner: sym }) | ||
} | ||
|
||
|
||
pub struct Symbol<'a> { | ||
inner: Frame, | ||
_unused: PhantomData<&'a ()> | ||
} | ||
|
||
impl<'a> Symbol<'a> { | ||
pub fn name(&self) -> Option<SymbolName> { | ||
Some(SymbolName::new(&self.inner.inner.name)) | ||
} | ||
|
||
pub fn addr(&self) -> Option<*mut c_void> { | ||
Some(self.inner.addr) | ||
} | ||
|
||
pub fn filename_raw(&self) -> Option<BytesOrWideString> { | ||
Some(BytesOrWideString::Bytes(&self.inner.inner.filename)) | ||
} | ||
|
||
pub fn lineno(&self) -> Option<u32> { | ||
Some(self.inner.inner.lineno) | ||
} | ||
|
||
pub fn colno(&self) -> Option<u32> { | ||
Some(self.inner.inner.colno) | ||
} | ||
|
||
pub fn filename(&self) -> Option<&::std::path::Path> { | ||
use std::path::Path; | ||
Some(Path::new(std::str::from_utf8(&self.inner.inner.filename).unwrap())) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters