Can I swap shared libraries on the fly?

I have some part of code written in go and used in rust as a shared library.
What I wonder is if I could just replace the .so file at runtime can the program pick up the canges without needing to restart or is there a way to inform the program to drop the cache if any exists without fully restarting the program

Yes, check out:

However, this is doable with libraries that have a C API. Rust doesn't have a stable ABI, and generics are problematic for shared libraries, so you won't be able to reload Rust code this way unless you give it a C API.

3 Likes

Reloading a dynamic lib does invalidate the previous function pointers obtained from it, does it not?

That's something to be very mindful of, since Rust's fn pointers behave as &'static code.

For instance, the following code is unsound:

extern crate libloading as lib;

fn unsound () -> extern "C" fn() -> u32
{
    let lib = lib::Library::new("/path/to/liblibrary.so").unwrap();
    let func: lib::Symbol<extern "C" fn() -> u32> = unsafe {
        // Safety: we perfectly control the run environment and know
        // that liblibrary.so contains a safe / sound `uint32_t my_func();`
        lib.get(b"my_func\0").unwrap()
    }
    *func
} // lib is dropped here; the function is no longer accessible 

For those wondering why the lifetime-constrained Symbol<'lib, fn...> is able to yield an unconstrained fn... this is because it offers an unsound Deref impl: for <'symbol> where 'lib : 'symbol, we have &'symbol Symbol<'lib, fn...> -> &'symbol fn... i.e., a &'symbol &'static code and since &_ are Copy / fns are Copy, we can use the * read-copy operator to "remove" the constraining &'symbol part, resulting in an unconstrained &'static code / fn.

In general, wrappers that try to artificially shrink lifetimes must be careful not to offer a generic Deref, since the Target can be Clone and escape the lifetime of the wrapper.

And with DerefMut it gets worse: even when the Target is not Clone, if one can forge a different unconstrained Target, mem::replace allows escaping that lifetime.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.