Module initialization/teardown functions for Rust (like
__attribute__((constructor)) in C/C++) for Linux, OSX, FreeBSD, NetBSD, Illumos, OpenBSD, DragonFlyBSD, Android, iOS, and Windows.
This library currently requires Rust > 1.31.0 at a minimum for the procedural macro support.
Idea inspired by this code in the Neon project.
This library works and is regularly tested
on Linux, OSX and Windows, with both
-crt-static. Other platforms are supported
but not tested as part of the automatic builds. This library will also work as expected in both
cdylib outputs, ie: the
dtor will run at executable or library
Rust's philosophy is that nothing happens before or after main and
this library explicitly subverts that. The code that runs in the
dtor functions should be careful to limit itself to
functions and code that does not rely on Rust's stdlib services.
For example, using stdout in a
dtor function is a guaranteed panic. Consider
libc-print crate for output
to stderr/stdout during
#[dtor] methods. Other issues
may involve signal processing or panic handling in that early code.
In most cases,
sys_common::at_exit is a better choice than
#[dtor]. Caveat emptor!
On some platforms, unloading of shared libraries may not actually happen until process exit, even if explicitly unloaded. The rules for this are arcane and difficult to understand. For example, thread-local storage on OSX will affect this (see this comment).
Marks the function
foo as a module constructor, called when a static
library is loaded or an executable is started:
static INITED: AtomicBool = new;
HashMap populated with strings when a static
library is loaded or an executable is started (new in
/// This is an immutable static, evaluated at init time static STATIC_CTOR: = ;
Print a message at shutdown time. Note that Rust may have shut down some stdlib services at this time.
Under the Hood
#[ctor] macro makes use of linker sections to ensure that a
function is run at startup time.
The above example translates into the following Rust code (approximately):
static FOO: extern fn = ;
#[dtor] macro effectively creates a constructor that calls
libc::atexit with the provided function, ie roughly equivalent to: