From fdc2f75844cde593aa0a475c92cb45102c42ae89 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 23 Sep 2025 14:50:50 -0700 Subject: [PATCH 1/5] ci: update MSRV job to 1.88 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9b70e41a..fdd7a35f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -265,7 +265,7 @@ jobs: with: submodules: true - name: Install Rust - run: rustup update 1.82.0 --no-self-update && rustup default 1.82.0 + run: rustup update 1.88.0 --no-self-update && rustup default 1.88.0 - run: cargo build miri: From 9ce9ff6bd1bdc81f0ff865b9f000912bdb419fa2 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 23 Sep 2025 14:52:16 -0700 Subject: [PATCH 2/5] fix dylib-dep to unsafe-wrap no_mangle --- crates/dylib-dep/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/dylib-dep/src/lib.rs b/crates/dylib-dep/src/lib.rs index 20180779..a6ed6c0f 100644 --- a/crates/dylib-dep/src/lib.rs +++ b/crates/dylib-dep/src/lib.rs @@ -8,7 +8,7 @@ macro_rules! pos { }; } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn foo(outer: Pos, inner: fn(Pos, Pos)) { inner(outer, pos!()); } From c671dab61db8a493493ff9ec6e10b13a9ae1c552 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 23 Sep 2025 14:56:32 -0700 Subject: [PATCH 3/5] unsafe some extern C blocks --- crates/cpp_smoke_test/tests/smoke.rs | 2 +- crates/line-tables-only/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cpp_smoke_test/tests/smoke.rs b/crates/cpp_smoke_test/tests/smoke.rs index a303562f..bda98953 100644 --- a/crates/cpp_smoke_test/tests/smoke.rs +++ b/crates/cpp_smoke_test/tests/smoke.rs @@ -3,7 +3,7 @@ extern crate cpp_smoke_test; use std::sync::atomic::{AtomicBool, Ordering}; -extern "C" { +unsafe extern "C" { fn cpp_trampoline(func: extern "C" fn()) -> (); } diff --git a/crates/line-tables-only/src/lib.rs b/crates/line-tables-only/src/lib.rs index 860d3db5..cb9eb8cd 100644 --- a/crates/line-tables-only/src/lib.rs +++ b/crates/line-tables-only/src/lib.rs @@ -7,7 +7,7 @@ mod tests { pub type Callback = extern "C" fn(data: *mut c_void); - extern "C" { + unsafe extern "C" { fn foo(cb: Callback, data: *mut c_void); } From 7d52b2a118961134bf971c5ffd43e911a331cbbc Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 23 Sep 2025 13:50:14 -0700 Subject: [PATCH 4/5] update to edition 2024 and MSRV 1.88 This allows using let-chains in the code, but requires a repo-wide fmt. --- Cargo.toml | 6 ++---- crates/as-if-std/Cargo.toml | 2 +- crates/cpp_smoke_test/Cargo.toml | 2 +- crates/debuglink/Cargo.toml | 2 +- crates/dylib-dep/Cargo.toml | 2 +- crates/line-tables-only/Cargo.toml | 2 +- crates/macos_frames_test/Cargo.toml | 2 +- crates/without_debuginfo/Cargo.toml | 2 +- src/capture.rs | 4 ++-- src/lib.rs | 4 ++-- src/print.rs | 5 +++-- src/symbolize/gimli.rs | 2 +- src/symbolize/gimli/coff.rs | 6 +++--- src/symbolize/gimli/elf.rs | 12 ++++++------ src/symbolize/gimli/libs_aix.rs | 2 +- src/symbolize/gimli/libs_dl_iterate_phdr.rs | 2 +- src/symbolize/gimli/libs_macos.rs | 2 +- src/symbolize/gimli/libs_windows.rs | 2 +- src/symbolize/gimli/macho.rs | 2 +- src/symbolize/gimli/mmap_fake.rs | 2 +- src/symbolize/gimli/xcoff.rs | 6 +++--- src/symbolize/miri.rs | 2 +- src/symbolize/mod.rs | 2 +- tests/concurrent-panics.rs | 20 ++++++++++++-------- 24 files changed, 49 insertions(+), 46 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 78f5276e..046c5ae3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ A library to acquire a stack trace (backtrace) at runtime in a Rust program. """ autoexamples = true autotests = true -edition = "2021" +edition = "2024" exclude = ["/ci/"] -rust-version = "1.82.0" +rust-version = "1.88.0" [workspace] members = ['crates/cpp_smoke_test', 'crates/as-if-std'] @@ -99,12 +99,10 @@ required-features = ["std"] [[test]] name = "smoke" required-features = ["std"] -edition = '2021' [[test]] name = "accuracy" required-features = ["std"] -edition = '2021' [[test]] name = "concurrent-panics" diff --git a/crates/as-if-std/Cargo.toml b/crates/as-if-std/Cargo.toml index 897c4987..fce91022 100644 --- a/crates/as-if-std/Cargo.toml +++ b/crates/as-if-std/Cargo.toml @@ -2,7 +2,7 @@ name = "as-if-std" version = "0.1.0" authors = ["Alex Crichton "] -edition = "2021" +edition = "2024" publish = false [lib] diff --git a/crates/cpp_smoke_test/Cargo.toml b/crates/cpp_smoke_test/Cargo.toml index 4746ee0d..95c08010 100644 --- a/crates/cpp_smoke_test/Cargo.toml +++ b/crates/cpp_smoke_test/Cargo.toml @@ -2,7 +2,7 @@ name = "cpp_smoke_test" version = "0.1.0" authors = ["Nick Fitzgerald "] -edition = "2021" +edition = "2024" build = "build.rs" publish = false diff --git a/crates/debuglink/Cargo.toml b/crates/debuglink/Cargo.toml index f8323205..1a81ebc5 100644 --- a/crates/debuglink/Cargo.toml +++ b/crates/debuglink/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "debuglink" version = "0.1.0" -edition = "2021" +edition = "2024" publish = false [dependencies] diff --git a/crates/dylib-dep/Cargo.toml b/crates/dylib-dep/Cargo.toml index e6cc9c23..ac0acde6 100644 --- a/crates/dylib-dep/Cargo.toml +++ b/crates/dylib-dep/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "dylib-dep" version = "0.1.0" -edition = "2021" +edition = "2024" authors = [] publish = false diff --git a/crates/line-tables-only/Cargo.toml b/crates/line-tables-only/Cargo.toml index 9cdd22b4..6ec7b570 100644 --- a/crates/line-tables-only/Cargo.toml +++ b/crates/line-tables-only/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "line-tables-only" version = "0.1.0" -edition = "2021" +edition = "2024" publish = false [build-dependencies] diff --git a/crates/macos_frames_test/Cargo.toml b/crates/macos_frames_test/Cargo.toml index cab83d05..148990fd 100644 --- a/crates/macos_frames_test/Cargo.toml +++ b/crates/macos_frames_test/Cargo.toml @@ -2,7 +2,7 @@ name = "macos_frames_test" version = "0.1.0" authors = ["Aaron Hill "] -edition = "2021" +edition = "2024" publish = false [dependencies.backtrace] diff --git a/crates/without_debuginfo/Cargo.toml b/crates/without_debuginfo/Cargo.toml index 37f10a65..1fae1170 100644 --- a/crates/without_debuginfo/Cargo.toml +++ b/crates/without_debuginfo/Cargo.toml @@ -2,7 +2,7 @@ name = "without_debuginfo" version = "0.1.0" authors = ["Alex Crichton "] -edition = "2021" +edition = "2024" publish = false [dependencies.backtrace] diff --git a/src/capture.rs b/src/capture.rs index e7de8792..b22e0a3c 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -1,9 +1,9 @@ #![allow(clippy::from_over_into)] +use crate::PrintFmt; #[cfg(feature = "serde")] use crate::resolve; -use crate::PrintFmt; -use crate::{resolve_frame, trace, BacktraceFmt, Symbol, SymbolName}; +use crate::{BacktraceFmt, Symbol, SymbolName, resolve_frame, trace}; use core::ffi::c_void; use std::fmt; use std::path::{Path, PathBuf}; diff --git a/src/lib.rs b/src/lib.rs index 8e188351..613a685d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,11 +105,11 @@ extern crate std; #[allow(unused_extern_crates)] extern crate alloc; -pub use self::backtrace::{trace_unsynchronized, Frame}; +pub use self::backtrace::{Frame, trace_unsynchronized}; mod backtrace; pub use self::symbolize::resolve_frame_unsynchronized; -pub use self::symbolize::{resolve_unsynchronized, Symbol, SymbolName}; +pub use self::symbolize::{Symbol, SymbolName, resolve_unsynchronized}; mod symbolize; pub use self::types::BytesOrWideString; diff --git a/src/print.rs b/src/print.rs index 888840ee..758a40c3 100644 --- a/src/print.rs +++ b/src/print.rs @@ -43,8 +43,9 @@ impl<'a, 'b> BacktraceFmt<'a, 'b> { pub fn new( fmt: &'a mut fmt::Formatter<'b>, format: PrintFmt, - print_path: &'a mut (dyn FnMut(&mut fmt::Formatter<'_>, BytesOrWideString<'_>) -> fmt::Result - + 'b), + print_path: &'a mut ( + dyn FnMut(&mut fmt::Formatter<'_>, BytesOrWideString<'_>) -> fmt::Result + 'b + ), ) -> Self { BacktraceFmt { fmt, diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs index d7ff410c..cbc0b768 100644 --- a/src/symbolize/gimli.rs +++ b/src/symbolize/gimli.rs @@ -2,8 +2,8 @@ //! //! This is the default symbolication implementation for Rust. -use self::gimli::read::EndianSlice; use self::gimli::NativeEndian as Endian; +use self::gimli::read::EndianSlice; use self::mmap::Mmap; use self::stash::Stash; use super::BytesOrWideString; diff --git a/src/symbolize/gimli/coff.rs b/src/symbolize/gimli/coff.rs index 031afea0..6e8ada47 100644 --- a/src/symbolize/gimli/coff.rs +++ b/src/symbolize/gimli/coff.rs @@ -1,13 +1,13 @@ use super::mystd::path::Path; -use super::{gimli, Context, Endian, EndianSlice, Mapping, Stash}; +use super::{Context, Endian, EndianSlice, Mapping, Stash, gimli}; use alloc::sync::Arc; use alloc::vec::Vec; use core::convert::TryFrom; +use object::LittleEndian as LE; use object::pe::{ImageDosHeader, ImageSymbol}; +use object::read::StringTable; use object::read::coff::ImageSymbol as _; use object::read::pe::{ImageNtHeaders, ImageOptionalHeader, SectionTable}; -use object::read::StringTable; -use object::LittleEndian as LE; #[cfg(target_pointer_width = "32")] type Pe = object::pe::ImageNtHeaders32; diff --git a/src/symbolize/gimli/elf.rs b/src/symbolize/gimli/elf.rs index e32fbad4..fd9903d1 100644 --- a/src/symbolize/gimli/elf.rs +++ b/src/symbolize/gimli/elf.rs @@ -1,11 +1,11 @@ #![allow(clippy::useless_conversion)] +use super::Either; use super::mystd::ffi::OsStr; use super::mystd::fs; use super::mystd::os::unix::ffi::OsStrExt; use super::mystd::path::{Path, PathBuf}; -use super::Either; -use super::{gimli, Context, Endian, EndianSlice, Mapping, Stash}; +use super::{Context, Endian, EndianSlice, Mapping, Stash, gimli}; use alloc::string::String; use alloc::sync::Arc; use alloc::vec::Vec; @@ -13,9 +13,9 @@ use core::convert::{TryFrom, TryInto}; use core::str; #[cfg(feature = "ruzstd")] use object::elf::ELFCOMPRESS_ZSTD; -use object::elf::{ELFCOMPRESS_ZLIB, ELF_NOTE_GNU, NT_GNU_BUILD_ID, SHF_COMPRESSED}; -use object::read::elf::{CompressionHeader, FileHeader, SectionHeader, SectionTable, Sym}; +use object::elf::{ELF_NOTE_GNU, ELFCOMPRESS_ZLIB, NT_GNU_BUILD_ID, SHF_COMPRESSED}; use object::read::StringTable; +use object::read::elf::{CompressionHeader, FileHeader, SectionHeader, SectionTable, Sym}; use object::{BigEndian, Bytes, NativeEndian}; #[cfg(target_pointer_width = "32")] @@ -340,11 +340,11 @@ impl<'a> Object<'a> { } fn decompress_zlib(input: &[u8], output: &mut [u8]) -> Option<()> { + use miniz_oxide::inflate::TINFLStatus; use miniz_oxide::inflate::core::inflate_flags::{ TINFL_FLAG_PARSE_ZLIB_HEADER, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF, }; - use miniz_oxide::inflate::core::{decompress, DecompressorOxide}; - use miniz_oxide::inflate::TINFLStatus; + use miniz_oxide::inflate::core::{DecompressorOxide, decompress}; let (status, in_read, out_read) = decompress( &mut DecompressorOxide::new(), diff --git a/src/symbolize/gimli/libs_aix.rs b/src/symbolize/gimli/libs_aix.rs index 01270a71..0f385355 100644 --- a/src/symbolize/gimli/libs_aix.rs +++ b/src/symbolize/gimli/libs_aix.rs @@ -6,7 +6,7 @@ use super::{Library, LibrarySegment}; use alloc::borrow::ToOwned; use alloc::vec; use alloc::vec::Vec; -use core::ffi::{c_int, CStr}; +use core::ffi::{CStr, c_int}; use core::mem; const EXE_IMAGE_BASE: u64 = 0x100000000; diff --git a/src/symbolize/gimli/libs_dl_iterate_phdr.rs b/src/symbolize/gimli/libs_dl_iterate_phdr.rs index d52819f6..2d1da7ca 100644 --- a/src/symbolize/gimli/libs_dl_iterate_phdr.rs +++ b/src/symbolize/gimli/libs_dl_iterate_phdr.rs @@ -5,7 +5,7 @@ use super::mystd::env; use super::mystd::ffi::{OsStr, OsString}; use super::mystd::os::unix::prelude::*; -use super::{parse_running_mmaps, Library, LibrarySegment}; +use super::{Library, LibrarySegment, parse_running_mmaps}; use alloc::borrow::ToOwned; use alloc::vec::Vec; use core::ffi::CStr; diff --git a/src/symbolize/gimli/libs_macos.rs b/src/symbolize/gimli/libs_macos.rs index f65811b2..c9c7dd2d 100644 --- a/src/symbolize/gimli/libs_macos.rs +++ b/src/symbolize/gimli/libs_macos.rs @@ -25,9 +25,9 @@ pub(super) fn native_libraries() -> Vec { } fn native_library(i: u32) -> Option { + use object::NativeEndian; use object::macho; use object::read::macho::{MachHeader, Segment}; - use object::NativeEndian; // Fetch the name of this library which corresponds to the path of // where to load it as well. diff --git a/src/symbolize/gimli/libs_windows.rs b/src/symbolize/gimli/libs_windows.rs index 1d9a74cc..7dca7f29 100644 --- a/src/symbolize/gimli/libs_windows.rs +++ b/src/symbolize/gimli/libs_windows.rs @@ -1,6 +1,6 @@ use super::super::super::windows_sys::*; use super::mystd::ffi::OsString; -use super::{coff, mmap, Library, LibrarySegment}; +use super::{Library, LibrarySegment, coff, mmap}; use alloc::vec; use alloc::vec::Vec; use core::mem; diff --git a/src/symbolize/gimli/macho.rs b/src/symbolize/gimli/macho.rs index fcbe6098..7112694d 100644 --- a/src/symbolize/gimli/macho.rs +++ b/src/symbolize/gimli/macho.rs @@ -1,5 +1,5 @@ use super::mystd::path::Path; -use super::{gimli, Context, Endian, EndianSlice, Mapping, Stash}; +use super::{Context, Endian, EndianSlice, Mapping, Stash, gimli}; use alloc::boxed::Box; use alloc::sync::Arc; use alloc::vec::Vec; diff --git a/src/symbolize/gimli/mmap_fake.rs b/src/symbolize/gimli/mmap_fake.rs index 71697fc3..c1435011 100644 --- a/src/symbolize/gimli/mmap_fake.rs +++ b/src/symbolize/gimli/mmap_fake.rs @@ -1,5 +1,5 @@ -use super::mystd::io::{Read, Seek, SeekFrom}; use super::File; +use super::mystd::io::{Read, Seek, SeekFrom}; use alloc::vec::Vec; use core::ops::Deref; diff --git a/src/symbolize/gimli/xcoff.rs b/src/symbolize/gimli/xcoff.rs index 51f00a8a..226bd4d4 100644 --- a/src/symbolize/gimli/xcoff.rs +++ b/src/symbolize/gimli/xcoff.rs @@ -1,17 +1,17 @@ use super::mystd::ffi::OsStr; use super::mystd::os::unix::ffi::OsStrExt; use super::mystd::path::Path; -use super::{gimli, Context, Endian, EndianSlice, Mapping, Stash}; +use super::{Context, Endian, EndianSlice, Mapping, Stash, gimli}; use alloc::sync::Arc; use alloc::vec::Vec; use core::ops::Deref; use core::str; -use object::read::archive::ArchiveFile; -use object::read::xcoff::{FileHeader, SectionHeader, XcoffFile, XcoffSymbol}; use object::Object as _; use object::ObjectSection as _; use object::ObjectSymbol as _; use object::SymbolFlags; +use object::read::archive::ArchiveFile; +use object::read::xcoff::{FileHeader, SectionHeader, XcoffFile, XcoffSymbol}; #[cfg(target_pointer_width = "32")] type Xcoff = object::xcoff::FileHeader32; diff --git a/src/symbolize/miri.rs b/src/symbolize/miri.rs index 5b0dc308..70f8b2a8 100644 --- a/src/symbolize/miri.rs +++ b/src/symbolize/miri.rs @@ -1,7 +1,7 @@ use core::ffi::c_void; use core::marker::PhantomData; -use super::super::backtrace::miri::{resolve_addr, Frame}; +use super::super::backtrace::miri::{Frame, resolve_addr}; use super::BytesOrWideString; use super::{ResolveWhat, SymbolName}; diff --git a/src/symbolize/mod.rs b/src/symbolize/mod.rs index 62714f04..d221ce80 100644 --- a/src/symbolize/mod.rs +++ b/src/symbolize/mod.rs @@ -10,7 +10,7 @@ cfg_if::cfg_if! { use super::backtrace::Frame; use super::types::BytesOrWideString; use core::ffi::c_void; -use rustc_demangle::{try_demangle, Demangle}; +use rustc_demangle::{Demangle, try_demangle}; /// Resolve an address to a symbol, passing the symbol to the specified /// closure. diff --git a/tests/concurrent-panics.rs b/tests/concurrent-panics.rs index 350c247d..8cd905aa 100644 --- a/tests/concurrent-panics.rs +++ b/tests/concurrent-panics.rs @@ -1,8 +1,8 @@ use std::env; use std::panic; use std::process::Command; -use std::sync::atomic::{AtomicBool, Ordering::SeqCst}; use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering::SeqCst}; use std::thread; const PANICS: usize = 100; @@ -45,9 +45,11 @@ fn parent() { fn child() { let done = Arc::new(AtomicBool::new(false)); let done2 = done.clone(); - let a = thread::spawn(move || loop { - if done2.load(SeqCst) { - break format!("{:?}", backtrace::Backtrace::new()); + let a = thread::spawn(move || { + loop { + if done2.load(SeqCst) { + break format!("{:?}", backtrace::Backtrace::new()); + } } }); @@ -55,10 +57,12 @@ fn child() { .map(|_| { thread::spawn(|| { for _ in 0..PANICS { - assert!(panic::catch_unwind(|| { - panic!(); - }) - .is_err()); + assert!( + panic::catch_unwind(|| { + panic!(); + }) + .is_err() + ); } }) }) From 3ae44567717bd28cb313b12a39266b20393bcf19 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 26 Sep 2025 10:47:38 -0700 Subject: [PATCH 5/5] unsafe-wrap a stray deref-project -> &raw --- src/symbolize/dbghelp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/symbolize/dbghelp.rs b/src/symbolize/dbghelp.rs index 243eb277..62ce30c8 100644 --- a/src/symbolize/dbghelp.rs +++ b/src/symbolize/dbghelp.rs @@ -245,8 +245,8 @@ unsafe fn do_resolve( // the real value. // SAFETY: We assume NameLen has been initialized by SymFromAddrW, and we initialized MaxNameLen let name_len = unsafe { cmp::min((*info).NameLen as usize, (*info).MaxNameLen as usize - 1) }; - // Name must be initialized by SymFromAddrW, but we only interact with it as a pointer anyways. - let name_ptr = (&raw const (*info).Name).cast::(); + // SAFETY: Name must be initialized by SymFromAddrW, but we only interact with it as a pointer anyways. + let name_ptr = unsafe { (&raw const (*info).Name).cast::() }; // Reencode the utf-16 symbol to utf-8 so we can use `SymbolName::new` like // all other platforms