Skip to content

Commit 72f0309

Browse files
committed
add support for new miri backtrace api
1 parent 5e15d73 commit 72f0309

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

src/backtrace/miri.rs

+43-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
use alloc::boxed::Box;
2+
use alloc::vec::Vec;
23
use core::ffi::c_void;
34

45
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 ());
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)]
1113
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 {
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)]
2031
pub 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) {
5465
pub 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

6494
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+
66103
for ptr in frames.iter() {
67104
let frame = resolve_addr(*ptr as *mut c_void);
68105
cb(&super::Frame { inner: frame });

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
#[macro_use]
106106
extern crate std;
107107

108-
// This is only used for gimli right now, which is only used on some platforms,
108+
// This is only used for gimli right now, which is only used on some platforms, and miri
109109
// so don't worry if it's unused in other configurations.
110110
#[allow(unused_extern_crates)]
111111
extern crate alloc;

0 commit comments

Comments
 (0)