From d386cd38907beca639672a9bedd67607ccd37260 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:42:49 +0100 Subject: [PATCH] Preserve assertion code for the cdylib panic handler --- libbz2-rs-sys-cdylib/Cargo.toml | 3 ++- libbz2-rs-sys-cdylib/src/lib.rs | 6 +++++- libbz2-rs-sys/src/lib.rs | 10 ++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libbz2-rs-sys-cdylib/Cargo.toml b/libbz2-rs-sys-cdylib/Cargo.toml index fe75dd69b..47e359016 100644 --- a/libbz2-rs-sys-cdylib/Cargo.toml +++ b/libbz2-rs-sys-cdylib/Cargo.toml @@ -6,7 +6,7 @@ license = "bzip2-1.0.6" repository = "https://github.com/trifectatechfoundation/libbzip2-rs" homepage = "https://github.com/trifectatechfoundation/libbzip2-rs" readme = "./README.md" -description = "a drop-in compatible libbz2 cdylib" +description = "a drop-in compatible libbz2 cdylib" publish = true rust-version = "1.82" # MSRV @@ -14,6 +14,7 @@ rust-version = "1.82" # MSRV name = "bz2_rs" # turns into e.g. `libbz2_rs.so` crate-type = ["cdylib"] test = false +bench = false [features] default = ["stdio"] diff --git a/libbz2-rs-sys-cdylib/src/lib.rs b/libbz2-rs-sys-cdylib/src/lib.rs index 0fdc94927..afcded9d4 100644 --- a/libbz2-rs-sys-cdylib/src/lib.rs +++ b/libbz2-rs-sys-cdylib/src/lib.rs @@ -37,11 +37,15 @@ fn panic_handler(_info: &PanicInfo) -> ! { #[cfg(not(feature = "stdio"))] { + use core::sync::atomic::Ordering; + extern "C" { fn bz_internal_error(errcode: core::ffi::c_int); } - unsafe { bz_internal_error(-1) } + // If the panic was triggered by handle_assert_failure ASSERT_CODE will contain the + // assertion code. Otherwise it will contain -1. + unsafe { bz_internal_error(ASSERT_CODE.load(Ordering::Relaxed)) } loop {} } } diff --git a/libbz2-rs-sys/src/lib.rs b/libbz2-rs-sys/src/lib.rs index 88f950253..35c18ab3a 100644 --- a/libbz2-rs-sys/src/lib.rs +++ b/libbz2-rs-sys/src/lib.rs @@ -11,6 +11,8 @@ extern crate std; use core::ffi::c_int; +#[cfg(not(feature = "std"))] +use core::sync::atomic::{AtomicI32, Ordering}; mod allocator; mod blocksort; @@ -135,6 +137,10 @@ macro_rules! assert_h { }; } +#[cfg(not(feature = "std"))] +#[doc(hidden)] +pub static ASSERT_CODE: AtomicI32 = AtomicI32::new(-1); + #[cold] fn handle_assert_failure(errcode: c_int) -> ! { #[cfg(feature = "std")] @@ -142,6 +148,10 @@ fn handle_assert_failure(errcode: c_int) -> ! { #[cfg(feature = "std")] std::process::exit(3); + // Stash the assertion code for the panic handler in the cdylib to pass to bz_internal_error. + // Using relaxed ordering as this will be accessed on the same thread. + #[cfg(not(feature = "std"))] + ASSERT_CODE.store(errcode as i32, Ordering::Relaxed); #[cfg(not(feature = "std"))] panic!("{}", AssertFail(errcode)); }