Skip to main content

Crate dtor

Crate dtor 

Source
Expand description

Build Status

The crate is part of the linktime project.

cratedocsversion
linktimedocs.rscrates.io
ctordocs.rscrates.io
dtordocs.rscrates.io
link-sectiondocs.rscrates.io

§dtor

Shutdown functions for Rust (like __attribute__((destructor)) in C/C++) for Linux, OSX, Windows, mobile (iOS/Android), WASM, BSD/BSD-likes and many other platforms.

use dtor::dtor;

#[dtor(unsafe)]
fn foo() {
    println!("Life after main!");
}

§Examples

Print a message at shutdown time.

#[dtor(unsafe)]
fn shutdown() {
    // Using println! or eprintln! here may panic as Rust may have
    // shut down some stdlib services at this time.
    libc_println!("Shutting down!");
}

§Platform Support

PlatformLink Sectionat_binary_exitat_module_exit
Linux.fini_arrayYes (atexit)Yes (__cxa_atexit)
MacOS.mod_term_func 🍎Yes (atexit)Yes (__cxa_atexit)
Windows.CRT$XPU 🪟NoYes (atexit)
AIXNo 🔵YesYes
Other POSIX-like platforms.fini_array/.dtorsYes (atexit)Yes (__cxa_atexit)

Notes:

  • 🍎 Not recommended. Apple platforms no longer call mod_term_func functions.
  • 🪟 Not recommended. Windows platforms may not reliably call functions in link sections, unless a binary is built with a static CRT.
  • 🔵 Link sections are not supported on AIX, but the platform calls functions with the prefix __sinit and __sterm at startup and shutdown respectively.

§Shutdown Method (#[dtor(method = ...)])

The #[dtor] macro supports multiple registration strategies via #[dtor(method = ...)]. The best choice is platform-dependent:

  • #[dtor] (no method specified): Use the platform’s most reliable method: at_module_exit on Windows and Apple platforms, and linker on others.
  • unload: Run on module unload (library unload or process exit) using the platform’s default unload method.
  • term: Run on process termination only using the platform’s default termination method. Not recommended: code may be unloaded before the dtor runs.
  • at_module_exit: Register using __cxa_atexit (non-Windows) or atexit (Windows) so the dtor runs when the module unloads.
  • at_binary_exit: Register to run at process exit (unsupported on Windows).
  • linker: Register using the platform’s linker mechanism (link_section on all platforms with the exception of export_name_prefix on AIX). Unsupported on Apple platforms.

Default:

  • Apple and Windows default to at_module_exit
  • Most other platforms default to linker

Examples:

use dtor::dtor;
/// Use `at_module_exit` on all platforms
#[dtor(unsafe, method = at_module_exit)]
fn shutdown() {}
use dtor::dtor;

/// Use `link_section` with a section name of `.dtors` on most platforms,
/// and `export_name_prefix` on AIX
#[dtor(unsafe, method = linker, link_section = ".dtors")]
fn shutdown() {}

§Warnings

Rust’s philosophy is that nothing happens before or after main and this library explicitly subverts that. The code that runs in the ctor and dtor functions should be careful to limit itself to libc functions and code that does not rely on Rust’s stdlib services.

See ::life_before_main for more information.

§Under the Hood

The #[dtor] macro effectively creates a constructor that calls libc::atexit with the provided function, i.e. roughly equivalent to:

#[ctor]
fn dtor_atexit() {
    libc::atexit(dtor);
}

§Crate Features

Cargo featureDescription
no_warn_on_missing_unsafeDo not warn when a ctor or dtor is missing the unsafe keyword.
proc_macroEnable support for the proc-macro #[dtor] attribute. The declarative form (dtor!(...)) is always available. It is recommended that crates re-exporting the dtor macro disable this feature and only use the declarative form.
stdEnable support for the standard library.
used_linkerApplies used(linker) to all dtor-generated functions. Requires nightly and feature(used_with_arg).

§Macro Attributes

AttributeDescription
anonymous

Make the ctor function anonymous.

crate_path = $path : pat

Specify a custom crate path for the dtor crate. Used when re-exporting the dtor macro.

ctor(export_name_prefix = $ctor_export_name_prefix_str : literal)

Specify a custom export name prefix for the constructor function.

If specified, an export with the given prefix will be generated in the form:

<prefix>_<unique_id>

ctor(link_section = $ctor_link_section_name : literal)

Place the initialization function pointer in a custom link section.

export_name_prefix = $export_name_prefix_str : literal

Specify a custom export name prefix for the destructor function.

If specified, an export with the given prefix will be generated in the form:

<prefix>_<unique_id>

link_section = $section : literal

Place the destructor function pointer in a custom link section.

method = $method_id : ident

Specify the dtor method.

  • term: Run the dtor on binary termination using the platform’s default_term_method. Not recommended as code may be unloaded before the dtor is called.
  • unload: Run the dtor on module unload (library or binary) using the platform’s default_unload_method.
  • at_module_exit: Run the dtor using the platform’s at_module_exit (__cxa_atexit on all platforms other than Windows, atexit on Windows).
  • at_binary_exit: Run the dtor using the platform’s at_binary_exit (unsupported on Windows platforms).
  • linker: Register the dtor using the platform’s link_section or export_name_prefix (unsupported on Apple platforms).
unsafe

Marks a ctor/dtor as unsafe.

used(linker)

Mark generated functions for this dtor as used(linker). Requires nightly and feature(used_with_arg).

§Defaults

§ctor_export_name_prefix

#[cfg(target_os = "aix")]
ctor_export_name_prefix = "__sinit80000000"

// default
ctor_export_name_prefix = ()
#[cfg(target_vendor = "apple")]
ctor_link_section = "__DATA,__mod_init_func,mod_init_funcs"

#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd",
target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly",
target_os = "illumos", target_os = "haiku", target_os = "vxworks", target_os =
"nto", target_family = "wasm"))]
ctor_link_section = ".init_array"

#[cfg(target_os = "none")]
ctor_link_section = ".init_array"

#[cfg(target_arch = "xtensa")]
ctor_link_section = ".ctors"

#[cfg(all(target_vendor = "pc", any(target_env = "gnu", target_env = "msvc")))]
ctor_link_section = ".CRT$XCU"

#[cfg(all(target_vendor = "pc", not(any(target_env = "gnu", target_env = "msvc"))))]
ctor_link_section = ".ctors"

#[cfg(all(target_os = "aix"))]
ctor_link_section = ()

// default
ctor_link_section = (compile_error! ("Unsupported target for #[ctor]"))

§default_term_method

#[cfg(target_vendor = "pc")]
default_term_method = at_module_exit

// default
default_term_method = at_binary_exit

§default_unload_method

// default
default_unload_method = at_module_exit

§export_name_prefix

#[cfg(target_os = "aix")]
export_name_prefix = "__sterm80000000"

// default
export_name_prefix = ()
#[cfg(target_vendor = "apple")]
link_section = "__DATA,__mod_term_func,mod_term_funcs"

#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd",
target_os = "netbsd", target_os = "openbsd", target_os = "dragonfly",
target_os = "illumos", target_os = "haiku", target_os = "vxworks", target_os =
"nto", target_family = "wasm"))]
link_section = ".fini_array"

#[cfg(target_os = "none")]
link_section = ".fini_array"

#[cfg(target_arch = "xtensa")]
link_section = ".dtors"

#[cfg(all(target_vendor = "pc", any(target_env = "gnu", target_env = "msvc")))]
link_section = ".CRT$XPU"

#[cfg(all(target_vendor = "pc", not(any(target_env = "gnu", target_env = "msvc"))))]
link_section = ".dtors"

#[cfg(all(target_os = "aix"))]
link_section = ()

// default
link_section = (compile_error! ("Unsupported target for #[dtor]"))

§method

#[cfg(target_vendor = "apple")]
method = at_module_exit

#[cfg(target_vendor = "pc")]
method = at_module_exit

// default
method = linker

Modules§

declarative
Declarative forms of the #[dtor] macro.
life_before_main
Life-Before-Main and Other Link-Time Hazards

Functions§

at_binary_exit
Registers a raw function to be called at binary exit time.
at_module_exit
Registers a raw function to be called at library (libc calls this a DSO or “dynamic shared object”) exit time.

Attribute Macros§

dtor
Marks a function as a library/executable destructor. This uses OS-specific linker sections to call a specific function at termination time.