11use alloc:: boxed:: Box ;
2+ use alloc:: vec:: Vec ;
23use core:: ffi:: c_void;
34
45extern "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 ( ) ) ;
68 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 ) ;
710}
811
9- #[ derive( Clone , Debug ) ]
1012#[ repr( C ) ]
1113pub 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 {
1223 pub name : Box < [ u8 ] > ,
1324 pub filename : Box < [ u8 ] > ,
1425 pub lineno : u32 ,
@@ -19,7 +30,7 @@ pub struct MiriFrame {
1930#[ derive( Debug , Clone ) ]
2031pub struct Frame {
2132 pub addr : * mut c_void ,
22- pub inner : MiriFrame ,
33+ pub inner : FullMiriFrame ,
2334}
2435
2536// SAFETY: Miri guarantees that the returned pointer
@@ -54,15 +65,41 @@ pub fn trace<F: FnMut(&super::Frame) -> bool>(cb: F) {
5465pub fn resolve_addr ( ptr : * mut c_void ) -> Frame {
5566 // SAFETY: Miri will stop execution with an error if this pointer
5667 // 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+
5882 Frame {
5983 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+ } ,
6191 }
6292}
6393
6494pub 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+
66103 for ptr in frames. iter ( ) {
67104 let frame = resolve_addr ( * ptr as * mut c_void ) ;
68105 cb ( & super :: Frame { inner : frame } ) ;
0 commit comments