1
1
use alloc:: boxed:: Box ;
2
+ use alloc:: vec:: Vec ;
2
3
use core:: ffi:: c_void;
3
4
4
5
extern "Rust" {
5
- fn miri_get_backtrace ( flags : u64 ) -> Box < [ * mut ( ) ] > ;
6
+ fn miri_backtrace_size ( flags : u64 ) -> usize ;
7
+ fn miri_get_backtrace ( flags : u64 , buf : * mut * mut ( ) ) ;
6
8
fn miri_resolve_frame ( ptr : * mut ( ) , flags : u64 ) -> MiriFrame ;
9
+ fn miri_resolve_frame_names ( ptr : * mut ( ) , flags : u64 , name_buf : * mut u8 , filename_buf : * mut u8 ) ;
7
10
}
8
11
9
- #[ derive( Clone , Debug ) ]
10
12
#[ repr( C ) ]
11
13
pub struct MiriFrame {
14
+ pub name_len : usize ,
15
+ pub filename_len : usize ,
16
+ pub lineno : u32 ,
17
+ pub colno : u32 ,
18
+ pub fn_ptr : * mut c_void ,
19
+ }
20
+
21
+ #[ derive( Clone , Debug ) ]
22
+ pub struct FullMiriFrame {
12
23
pub name : Box < [ u8 ] > ,
13
24
pub filename : Box < [ u8 ] > ,
14
25
pub lineno : u32 ,
@@ -19,7 +30,7 @@ pub struct MiriFrame {
19
30
#[ derive( Debug , Clone ) ]
20
31
pub struct Frame {
21
32
pub addr : * mut c_void ,
22
- pub inner : MiriFrame ,
33
+ pub inner : FullMiriFrame ,
23
34
}
24
35
25
36
// SAFETY: Miri guarantees that the returned pointer
@@ -54,15 +65,41 @@ pub fn trace<F: FnMut(&super::Frame) -> bool>(cb: F) {
54
65
pub fn resolve_addr ( ptr : * mut c_void ) -> Frame {
55
66
// SAFETY: Miri will stop execution with an error if this pointer
56
67
// is invalid.
57
- let frame: MiriFrame = unsafe { miri_resolve_frame ( ptr as * mut ( ) , 0 ) } ;
68
+ let frame = unsafe { miri_resolve_frame ( ptr as * mut ( ) , 1 ) } ;
69
+
70
+ let mut name = Vec :: with_capacity ( frame. name_len ) ;
71
+ let mut filename = Vec :: with_capacity ( frame. filename_len ) ;
72
+
73
+ // SAFETY: name and filename have been allocated with the amount
74
+ // of memory miri has asked for, and miri guarantees it will initialize it
75
+ unsafe {
76
+ miri_resolve_frame_names ( ptr as * mut ( ) , 1 , name. as_mut_ptr ( ) , filename. as_mut_ptr ( ) ) ;
77
+
78
+ name. set_len ( frame. name_len ) ;
79
+ filename. set_len ( frame. filename_len ) ;
80
+ }
81
+
58
82
Frame {
59
83
addr : ptr,
60
- inner : frame,
84
+ inner : FullMiriFrame {
85
+ name : name. into ( ) ,
86
+ filename : filename. into ( ) ,
87
+ lineno : frame. lineno ,
88
+ colno : frame. colno ,
89
+ fn_ptr : frame. fn_ptr ,
90
+ } ,
61
91
}
62
92
}
63
93
64
94
pub unsafe fn trace_unsynchronized < F : FnMut ( & super :: Frame ) -> bool > ( mut cb : F ) {
65
- let frames = miri_get_backtrace ( 0 ) ;
95
+ let len = miri_backtrace_size ( 1 ) ;
96
+
97
+ let mut frames = Vec :: with_capacity ( len) ;
98
+
99
+ miri_get_backtrace ( 1 , frames. as_mut_ptr ( ) ) ;
100
+
101
+ frames. set_len ( len) ;
102
+
66
103
for ptr in frames. iter ( ) {
67
104
let frame = resolve_addr ( * ptr as * mut c_void ) ;
68
105
cb ( & super :: Frame { inner : frame } ) ;
0 commit comments