LD_PRELOAD init function in Rust?

Per this StackOverflow answer, if you want a function to be executed in a shared library as soon as that library is loaded (e.g., with LD_PRELOAD), you can pass this flag to ld: -init <function name>. Is there a way of doing the same thing in Rust (that is, to mark a Rust function as being run in this manner)?

In FFI attributes, one is link_args (feature-gated). I suppose you could use it something like #[link_args = "-Wl,-init,function_name"]. Or at the rustc command line, there's always -Clink-arg=...

Awesome, thanks! So I got it working on Linux using #![link_args = "-Wl,-init,init_log"] (a crate-level attribute), but when I compile the same code on Mac, I get an error:

ld: entry point (init_log) undefined. for architecture x86_64

The code is very straightforward, so I'm not sure what I'm doing wrong. Do you have any ideas?

EDIT: Also, on Linux, I get this strange unused attribute warning:

warning: unused attribute
 --> src/lib.rs:9:34
9 | #![cfg_attr(feature = "logging", link_args = "-Wl,-init,init_log")]
  |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: #[warn(unused_attributes)] on by default

The docs say it's an attribute for extern blocks, so maybe instead of using it crate-level, put it on an empty extern {} ?

Unfortunately it still gives me the unused warning (on both platforms) and fails to link on Mac.

On macOS, the C ABI prefixes all symbols with _ (underscore), but ld doesn't know about that. So try -Wl,-init,_init_log.

That said, as a matter of design, if you're just using this to initialize logging (as opposed to some hooking thing that really needs to run on startup), are you sure you can't use lazy_static or similar instead? :slight_smile:

That worked, thanks so much!

With respect to the design, this is in a library that provides allocation routines, so the only other way to initialize would be to to use lazy_static or something in the hot path of each call, which would cause performance degradation. Granted, logging probably does too, but we'd like to avoid these kinds of costs if possible.