Skip to content

Commit

Permalink
Preserve assertion code for the cdylib panic handler
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 authored and folkertdev committed Dec 11, 2024
1 parent 78cc316 commit d386cd3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 2 deletions.
3 changes: 2 additions & 1 deletion libbz2-rs-sys-cdylib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ 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

[lib]
name = "bz2_rs" # turns into e.g. `libbz2_rs.so`
crate-type = ["cdylib"]
test = false
bench = false

[features]
default = ["stdio"]
Expand Down
6 changes: 5 additions & 1 deletion libbz2-rs-sys-cdylib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}
}
10 changes: 10 additions & 0 deletions libbz2-rs-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -135,13 +137,21 @@ 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")]
std::eprint!("{}", AssertFail(errcode));
#[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));
}
Expand Down

0 comments on commit d386cd3

Please sign in to comment.