File tree 4 files changed +131
-7
lines changed
4 files changed +131
-7
lines changed Original file line number Diff line number Diff line change
1
+ use std:: boxed:: Box ;
2
+ use std:: ffi:: c_void;
3
+
4
+ extern "Rust" {
5
+ fn miri_get_backtrace ( flags : u64 ) -> Box < [ * mut ( ) ] > ;
6
+ fn miri_resolve_frame ( ptr : * mut ( ) , flags : u64 ) -> MiriFrame ;
7
+ }
8
+
9
+ #[ derive( Clone , Debug ) ]
10
+ #[ repr( C ) ]
11
+ pub struct MiriFrame {
12
+ pub name : Box < [ u8 ] > ,
13
+ pub filename : Box < [ u8 ] > ,
14
+ pub lineno : u32 ,
15
+ pub colno : u32 ,
16
+ }
17
+
18
+ #[ derive( Debug , Clone ) ]
19
+ pub struct Frame {
20
+ pub addr : * mut c_void ,
21
+ pub inner : MiriFrame ,
22
+ }
23
+
24
+ // SAFETY: Miri guarantees that the returned pointer
25
+ // can be used from any thread.
26
+ unsafe impl Send for Frame { }
27
+ unsafe impl Sync for Frame { }
28
+
29
+ impl Frame {
30
+ pub fn ip ( & self ) -> * mut c_void {
31
+ self . addr
32
+ }
33
+
34
+ pub fn sp ( & self ) -> * mut c_void {
35
+ std:: ptr:: null_mut ( )
36
+ }
37
+
38
+ pub fn symbol_address ( & self ) -> * mut c_void {
39
+ self . addr
40
+ }
41
+
42
+ pub fn module_base_address ( & self ) -> Option < * mut c_void > {
43
+ None
44
+ }
45
+ }
46
+
47
+ pub fn trace < F : FnMut ( & super :: Frame ) -> bool > ( cb : F ) {
48
+ // SAFETY: Miri guarnatees that the backtrace API functions
49
+ // can be called from any thread.
50
+ unsafe { trace_unsynchronized ( cb) } ;
51
+ }
52
+
53
+ pub fn resolve_addr ( ptr : * mut c_void ) -> Frame {
54
+ // SAFETY: Miri will stop execution with an error if this pointer
55
+ // is invalid.
56
+ let frame: MiriFrame = unsafe { miri_resolve_frame ( ptr as * mut ( ) , 0 ) } ;
57
+ Frame {
58
+ addr : ptr,
59
+ inner : frame,
60
+ }
61
+ }
62
+
63
+ pub unsafe fn trace_unsynchronized < F : FnMut ( & super :: Frame ) -> bool > ( mut cb : F ) {
64
+ let frames = miri_get_backtrace ( 0 ) ;
65
+ for ptr in frames. iter ( ) {
66
+ let frame = resolve_addr ( * ptr as * mut c_void ) ;
67
+ cb ( & super :: Frame { inner : frame } ) ;
68
+ }
69
+ }
Original file line number Diff line number Diff line change @@ -126,10 +126,12 @@ impl fmt::Debug for Frame {
126
126
}
127
127
128
128
cfg_if:: cfg_if! {
129
+ // This needs to come first, to ensure that
130
+ // Miri takes priority over the host platform
129
131
if #[ cfg( miri) ] {
130
- mod noop ;
131
- use self :: noop :: trace as trace_imp;
132
- pub ( crate ) use self :: noop :: Frame as FrameImp ;
132
+ pub ( crate ) mod miri ;
133
+ use self :: miri :: trace as trace_imp;
134
+ pub ( crate ) use self :: miri :: Frame as FrameImp ;
133
135
} else if #[ cfg(
134
136
any(
135
137
all(
Original file line number Diff line number Diff line change
1
+ use core:: ffi:: c_void;
2
+ use core:: marker:: PhantomData ;
3
+
4
+ use crate :: backtrace:: miri:: { resolve_addr, Frame } ;
5
+ use crate :: symbolize:: { ResolveWhat , SymbolName } ;
6
+ use crate :: types:: BytesOrWideString ;
7
+
8
+ pub unsafe fn resolve ( what : ResolveWhat < ' _ > , cb : & mut dyn FnMut ( & super :: Symbol ) ) {
9
+ let sym = match what {
10
+ ResolveWhat :: Address ( addr) => Symbol {
11
+ inner : resolve_addr ( addr) ,
12
+ _unused : PhantomData ,
13
+ } ,
14
+ ResolveWhat :: Frame ( frame) => Symbol {
15
+ inner : frame. inner . clone ( ) ,
16
+ _unused : PhantomData ,
17
+ } ,
18
+ } ;
19
+ cb ( & super :: Symbol { inner : sym } )
20
+ }
21
+
22
+ pub struct Symbol < ' a > {
23
+ inner : Frame ,
24
+ _unused : PhantomData < & ' a ( ) > ,
25
+ }
26
+
27
+ impl < ' a > Symbol < ' a > {
28
+ pub fn name ( & self ) -> Option < SymbolName < ' _ > > {
29
+ Some ( SymbolName :: new ( & self . inner . inner . name ) )
30
+ }
31
+
32
+ pub fn addr ( & self ) -> Option < * mut c_void > {
33
+ Some ( self . inner . addr )
34
+ }
35
+
36
+ pub fn filename_raw ( & self ) -> Option < BytesOrWideString < ' _ > > {
37
+ Some ( BytesOrWideString :: Bytes ( & self . inner . inner . filename ) )
38
+ }
39
+
40
+ pub fn lineno ( & self ) -> Option < u32 > {
41
+ Some ( self . inner . inner . lineno )
42
+ }
43
+
44
+ pub fn colno ( & self ) -> Option < u32 > {
45
+ Some ( self . inner . inner . colno )
46
+ }
47
+
48
+ pub fn filename ( & self ) -> Option < & :: std:: path:: Path > {
49
+ use std:: path:: Path ;
50
+ Some ( Path :: new (
51
+ std:: str:: from_utf8 ( & self . inner . inner . filename ) . unwrap ( ) ,
52
+ ) )
53
+ }
54
+ }
Original file line number Diff line number Diff line change @@ -465,10 +465,9 @@ pub fn clear_symbol_cache() {
465
465
466
466
cfg_if:: cfg_if! {
467
467
if #[ cfg( miri) ] {
468
- mod noop;
469
- use self :: noop:: resolve as resolve_imp;
470
- use self :: noop:: Symbol as SymbolImp ;
471
- #[ allow( unused) ]
468
+ mod miri;
469
+ use self :: miri:: resolve as resolve_imp;
470
+ use self :: miri:: Symbol as SymbolImp ;
472
471
unsafe fn clear_symbol_cache_imp( ) { }
473
472
} else if #[ cfg( all( windows, target_env = "msvc" , not( target_vendor = "uwp" ) ) ) ] {
474
473
mod dbghelp;
You can’t perform that action at this time.
0 commit comments