Description
The question I have is the combination of the following code, using the swc_atoms
crate, with the alloc_error_hook
feature, as discussed by @LegionMammal978 in swc-project/swc#8362 (comment)
// cargo +nightly run --release --target i686-unknown-linux-gnu
#![forbid(unsafe_code)]
#![feature(alloc_error_hook)]
use std::alloc;
use swc_atoms::AtomStoreCell;
fn main() {
thread_local! {
static STORE: AtomStoreCell = AtomStoreCell::default();
}
alloc::set_alloc_error_hook(|_| {
STORE.with(|store| {
println!("start of inner call");
store.atom("example");
println!("end of inner call");
});
});
let vec = vec![0; isize::MAX as usize];
let s = String::from_utf8(vec).unwrap();
STORE.with(|store| {
println!("start of outer call");
store.atom(&s);
println!("end of outer call");
});
}
Essentially, because the data structure first obtains &mut
to itself via UnsafeCell, and then begins meddling with allocations, then if an allocation error handler is triggered during that moment and also obtains that &mut
, we get an aliasing &mut
. This makes the data structure's interface effectively unsound in the presence of the alloc error handler, and probably also panic handlers?
So the question is: is this data structure indeed unsound? But also, even if we decree AtomStoreCell unsound, this raises a question about these kinds of hooks and how we should teach making safe data structures in their presence, as it implies even !Sync
structures must worry about, effectively, reentrancy.