Skip to content

handle_alloc_error + UnsafeCell = ??? #479

Closed
@workingjubilee

Description

@workingjubilee

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions