Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Your process can be started in a paused state by a debugger, have new libraries and threads injected into it, and then resumed before a single instruction of your own binary has been executed... and debuggers are far from the only thing that will inject code into your processes. If you're willing to handwave that, pre-main constructors, etc. away, you can write something like this easily enough:

    struct BeforeEnvFreeze(());
    struct AfterEnvFreeze(());

    impl BeforeEnvFreeze {
        pub fn new() -> Self { /* singleton check using a static AtomicBool or something */ Self(()) }
        pub fn freeze(self) -> AfterEnvFreeze { AfterEnvFreeze(()) }
        pub fn set_env(&self, ...) { ... }
    }

    impl AfterEnvFreeze {
        pub fn spawn_thread(&self, ...) { ... }
    }

    fn main() {
        let a = BeforeEnvFreeze::new();
        a.set_env(...);
        a.set_env(...);
        //b.spawn_thread(...); // not available

        let b = a.freeze(); // consumes `a`

        b.spawn_thread(...);
        //a.set_env(...); // not available
    }
Exercises left to the reader:

• Banning access to the relevant bits of Rust's stdlib, libc, etc. as a means of escaping this "safe" abstraction

• Conning your lead developer into accepting your handwave

• Setting up the appropriate VCS alerts so you have a chance to NAK "helpful" "utility" pull requests that undermine your "protections"

And of course, this all remains a hackaround for POSIX design flaws - your engineering time might be better spent ensuring or enforcing your libc is "fixed" via intentional memory leaks per e.g. https://github.com/bminor/glibc/commit/7a61e7f557a97ab597d6f... , which may ≈fix more than your Rust programs.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: