mmastrac / rust-ctor

Module initialization/global constructor functions for Rust
Apache License 2.0
739 stars 49 forks source link

Add used_linker feature #281

Closed mmastrac closed 1 year ago

mmastrac commented 1 year ago

Add a feature used_linker that uses #[used(linker)], an unstable +nightly feature that might fix some of the ctor pain.

This may fix #280, #206 and related bugs.

stepancheg commented 1 year ago

The issue still reproduces with this example unfortunately: https://github.com/mmastrac/rust-ctor/issues/220

(There's something odd that feature is not enabled for proc macro dependency even if selected explicitly, but I patched ctor crate to include is unconditionally, and the problem still exists.)

In that repo:

cargo expand -p foo bar
mod bar {
    use crate::COUNTER;
    use std::sync::atomic::{Ordering, Ordering::SeqCst};
    use ctor::ctor;
    extern fn init() {
        COUNTER.store(COUNTER.load(SeqCst) + 1, Ordering::SeqCst)
    }
    #[used(linker)]
    #[allow(non_upper_case_globals)]
    #[doc(hidden)]
    #[link_section = "__DATA,__mod_init_func"]
    static init___rust_ctor___ctor: unsafe extern "C" fn() = {
        unsafe extern "C" fn init___rust_ctor___ctor() {
            init()
        }
        init___rust_ctor___ctor
    };
}

and yet

cargo +nightly run
The value of COUNTER is 2.
Why not 3?

macOS 13.4, Apple M1, rustc 1.72.0-nightly (871b59520 2023-05-31)