Skip to content

Commit 9d2c34e

Browse files
Merge of #700: Prepare backtrace for Rust 2024
This applies some fixes so that backtrace is compatible with Rust 2024. It is needed to migrate std to 2024 since std directly embeds backtrace.
2 parents 534a1d3 + 52b94f9 commit 9d2c34e

17 files changed

+292
-234
lines changed

.github/workflows/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ jobs:
256256
with:
257257
submodules: true
258258
- name: Install Rust
259-
run: rustup update 1.79.0 --no-self-update && rustup default 1.79.0
259+
run: rustup update 1.82.0 --no-self-update && rustup default 1.82.0
260260
- run: cargo build
261261

262262
miri:

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ autoexamples = true
1414
autotests = true
1515
edition = "2021"
1616
exclude = ["/ci/"]
17-
rust-version = "1.79.0"
17+
rust-version = "1.82.0"
1818

1919
[workspace]
2020
members = ['crates/cpp_smoke_test', 'crates/as-if-std']

src/backtrace/libunwind.rs

+26-20
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ impl Drop for Bomb {
113113

114114
#[inline(always)]
115115
pub unsafe fn trace(mut cb: &mut dyn FnMut(&super::Frame) -> bool) {
116-
uw::_Unwind_Backtrace(trace_fn, addr_of_mut!(cb).cast());
116+
unsafe {
117+
uw::_Unwind_Backtrace(trace_fn, addr_of_mut!(cb).cast());
118+
}
117119

118120
extern "C" fn trace_fn(
119121
ctx: *mut uw::_Unwind_Context,
@@ -168,7 +170,7 @@ mod uw {
168170
pub type _Unwind_Trace_Fn =
169171
extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut c_void) -> _Unwind_Reason_Code;
170172

171-
extern "C" {
173+
unsafe extern "C" {
172174
pub fn _Unwind_Backtrace(
173175
trace: _Unwind_Trace_Fn,
174176
trace_argument: *mut c_void,
@@ -186,7 +188,7 @@ mod uw {
186188
not(all(target_os = "vita", target_arch = "arm")),
187189
not(all(target_os = "nuttx", target_arch = "arm")),
188190
))] {
189-
extern "C" {
191+
unsafe extern "C" {
190192
pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
191193
pub fn _Unwind_FindEnclosingFunction(pc: *mut c_void) -> *mut c_void;
192194

@@ -206,10 +208,10 @@ mod uw {
206208
// instead of relying on _Unwind_GetCFA.
207209
#[cfg(all(target_os = "linux", target_arch = "s390x"))]
208210
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
209-
extern "C" {
211+
unsafe extern "C" {
210212
pub fn _Unwind_GetGR(ctx: *mut _Unwind_Context, index: libc::c_int) -> libc::uintptr_t;
211213
}
212-
_Unwind_GetGR(ctx, 15)
214+
unsafe { _Unwind_GetGR(ctx, 15) }
213215
}
214216
} else {
215217
use core::ptr::addr_of_mut;
@@ -246,7 +248,7 @@ mod uw {
246248
}
247249

248250
type _Unwind_Word = libc::c_uint;
249-
extern "C" {
251+
unsafe extern "C" {
250252
fn _Unwind_VRS_Get(
251253
ctx: *mut _Unwind_Context,
252254
klass: _Unwind_VRS_RegClass,
@@ -259,13 +261,15 @@ mod uw {
259261
pub unsafe fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
260262
let mut val: _Unwind_Word = 0;
261263
let ptr = addr_of_mut!(val);
262-
let _ = _Unwind_VRS_Get(
263-
ctx,
264-
_Unwind_VRS_RegClass::_UVRSC_CORE,
265-
15,
266-
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
267-
ptr.cast::<c_void>(),
268-
);
264+
unsafe {
265+
let _ = _Unwind_VRS_Get(
266+
ctx,
267+
_Unwind_VRS_RegClass::_UVRSC_CORE,
268+
15,
269+
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
270+
ptr.cast::<c_void>(),
271+
);
272+
}
269273
(val & !1) as libc::uintptr_t
270274
}
271275

@@ -275,13 +279,15 @@ mod uw {
275279
pub unsafe fn get_sp(ctx: *mut _Unwind_Context) -> libc::uintptr_t {
276280
let mut val: _Unwind_Word = 0;
277281
let ptr = addr_of_mut!(val);
278-
let _ = _Unwind_VRS_Get(
279-
ctx,
280-
_Unwind_VRS_RegClass::_UVRSC_CORE,
281-
SP,
282-
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
283-
ptr.cast::<c_void>(),
284-
);
282+
unsafe {
283+
let _ = _Unwind_VRS_Get(
284+
ctx,
285+
_Unwind_VRS_RegClass::_UVRSC_CORE,
286+
SP,
287+
_Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
288+
ptr.cast::<c_void>(),
289+
);
290+
}
285291
val as libc::uintptr_t
286292
}
287293

src/backtrace/miri.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloc::boxed::Box;
22
use alloc::vec::Vec;
33
use core::ffi::c_void;
44

5-
extern "Rust" {
5+
unsafe extern "Rust" {
66
fn miri_backtrace_size(flags: u64) -> usize;
77
fn miri_get_backtrace(flags: u64, buf: *mut *mut ());
88
fn miri_resolve_frame(ptr: *mut (), flags: u64) -> MiriFrame;
@@ -56,7 +56,10 @@ impl Frame {
5656
}
5757
}
5858

59-
pub fn trace<F: FnMut(&super::Frame) -> bool>(cb: F) {
59+
// SAFETY: This function is safe to call. It is only marked as `unsafe` to
60+
// avoid having to allow `unused_unsafe` since other implementations are
61+
// unsafe.
62+
pub unsafe fn trace<F: FnMut(&super::Frame) -> bool>(cb: F) {
6063
// SAFETY: Miri guarantees that the backtrace API functions
6164
// can be called from any thread.
6265
unsafe { trace_unsynchronized(cb) };
@@ -97,13 +100,15 @@ pub fn resolve_addr(ptr: *mut c_void) -> Frame {
97100
}
98101

99102
unsafe fn trace_unsynchronized<F: FnMut(&super::Frame) -> bool>(mut cb: F) {
100-
let len = miri_backtrace_size(0);
103+
let len = unsafe { miri_backtrace_size(0) };
101104

102105
let mut frames = Vec::with_capacity(len);
103106

104-
miri_get_backtrace(1, frames.as_mut_ptr());
107+
unsafe {
108+
miri_get_backtrace(1, frames.as_mut_ptr());
105109

106-
frames.set_len(len);
110+
frames.set_len(len);
111+
}
107112

108113
for ptr in frames.iter() {
109114
let frame = resolve_addr((*ptr).cast::<c_void>());

src/backtrace/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub fn trace<F: FnMut(&Frame) -> bool>(cb: F) {
6363
///
6464
/// See information on `trace` for caveats on `cb` panicking.
6565
pub unsafe fn trace_unsynchronized<F: FnMut(&Frame) -> bool>(mut cb: F) {
66-
trace_imp(&mut cb)
66+
unsafe { trace_imp(&mut cb) }
6767
}
6868

6969
/// A trait representing one frame of a backtrace, yielded to the `trace`

src/backtrace/noop.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
use core::ffi::c_void;
55
use core::ptr::null_mut;
66

7+
// SAFETY: This function is safe to call. It is only marked as `unsafe` to
8+
// avoid having to allow `unused_unsafe` since other implementations are
9+
// unsafe.
710
#[inline(always)]
8-
pub fn trace(_cb: &mut dyn FnMut(&super::Frame) -> bool) {}
11+
pub unsafe fn trace(_cb: &mut dyn FnMut(&super::Frame) -> bool) {}
912

1013
#[derive(Clone)]
1114
pub struct Frame;

src/backtrace/win64.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
8080
use core::ptr;
8181

8282
// Capture the initial context to start walking from.
83-
let mut context = core::mem::zeroed::<MyContext>();
84-
RtlCaptureContext(&mut context.0);
83+
// FIXME: shouldn't this have a Default impl?
84+
let mut context = unsafe { core::mem::zeroed::<MyContext>() };
85+
unsafe { RtlCaptureContext(&mut context.0) };
8586

8687
loop {
8788
let ip = context.ip();
@@ -93,7 +94,7 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
9394
// us to backtrace through JIT frames.
9495
// Note that `RtlLookupFunctionEntry` only works for in-process backtraces,
9596
// but that's all we support anyway, so it all lines up well.
96-
let fn_entry = RtlLookupFunctionEntry(ip, &mut base, ptr::null_mut());
97+
let fn_entry = unsafe { RtlLookupFunctionEntry(ip, &mut base, ptr::null_mut()) };
9798
if fn_entry.is_null() {
9899
// No function entry could be found - this may indicate a corrupt
99100
// stack or that a binary was unloaded (amongst other issues). Stop
@@ -124,16 +125,18 @@ pub unsafe fn trace(cb: &mut dyn FnMut(&super::Frame) -> bool) {
124125
let previous_sp = context.sp();
125126
let mut handler_data = 0usize;
126127
let mut establisher_frame = 0;
127-
RtlVirtualUnwind(
128-
0,
129-
base,
130-
ip,
131-
fn_entry,
132-
&mut context.0,
133-
ptr::addr_of_mut!(handler_data).cast::<*mut c_void>(),
134-
&mut establisher_frame,
135-
ptr::null_mut(),
136-
);
128+
unsafe {
129+
RtlVirtualUnwind(
130+
0,
131+
base,
132+
ip,
133+
fn_entry,
134+
&mut context.0,
135+
ptr::addr_of_mut!(handler_data).cast::<*mut c_void>(),
136+
&mut establisher_frame,
137+
ptr::null_mut(),
138+
);
139+
}
137140

138141
// RtlVirtualUnwind indicates the end of the stack in two different ways:
139142
// * On x64, it sets the instruction pointer to 0.

src/print/fuchsia.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::mem::{size_of, transmute};
33
use core::slice::from_raw_parts;
44
use libc::c_char;
55

6-
extern "C" {
6+
unsafe extern "C" {
77
// dl_iterate_phdr takes a callback that will receive a dl_phdr_info pointer
88
// for every DSO that has been linked into the process. dl_iterate_phdr also
99
// ensures that the dynamic linker is locked from start to finish of the
@@ -148,7 +148,7 @@ impl<'a> NoteIter<'a> {
148148
// can be anything but the range must be valid for this to be safe.
149149
unsafe fn new(base: *const u8, size: usize) -> Self {
150150
NoteIter {
151-
base: from_raw_parts(base, size),
151+
base: unsafe { from_raw_parts(base, size) },
152152
error: false,
153153
}
154154
}

0 commit comments

Comments
 (0)