Linker and Libraries Guide

Initialization and Termination Routines

Before transferring control to the application, the runtime linker processes any initialization (.init) and termination (.fini) sections found in the applications dependencies. These sections, and the symbols that describe them, are created during the link-editing of the dependencies (see "Initialization and Termination Sections").

Prior to the Solaris2.6 release, any initialization routines from dependencies were called in reverse load order - in other words, the reverse order of the dependencies displayed with ldd(1).

Starting with the Solaris2.6 release, the runtime linker constructs a dependency ordered list of initialization routines from the dependencies that have been loaded. This list is built from the dependency relationships expressed by each object, in addition to any bindings that occur outside of the expressed dependencies.

The .init sections are executed in the reverse topological order of the dependencies. If any cyclic dependencies are found, the objects that form the cycle cannot be topologically sorted, and thus their .init sections will be executed in the order they are loaded.

ldd(1) with the -i option can be used to display the initialization order of an objects' dependencies. For example, the following dynamic executable and its dependencies exhibit a cyclic dependency:


$ dump -Lv B.so.1 | grep NEEDED
[1]     NEEDED      C.so.1
$ dump -Lv C.so.1 | grep NEEDED
[1]     NEEDED      B.so.1
$ dump -Lv main | grep NEEDED
[1]     NEEDED      A.so.1
[2]     NEEDED      B.so.1
[3]     NEEDED      libc.so.1
$ ldd -i main
        A.so.1 =>        ./A.so.1
        B.so.1 =>        ./B.so.1
        libc.so.1 =>     /usr/lib/libc.so.1
        C.so.1 =>        ./C.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1

   init library=./A.so.1
   init library=./C.so.1 (cyclic dependency on ./B.so.1)
   init library=./B.so.1 (cyclic dependency on ./C.so.1)
   init library=/usr/lib/libc.so.1

The environment variable LD_BREADTH can be set to a non-null value to force the runtime linker to execute .init sections in pre-2.6 order.

Initialization processing is repeated for any objects added to the running process with dlopen(3X).

Any termination routines for an applications dependencies are organized such that they can be recorded by atexit(3C). These routines are called when the process calls exit(2), or when objects are removed from the running process with dlclose(3X).

Starting with the Solaris2.6 release, termination routines are called in the topological order of dependencies. Prior to the Solaris2.6 release, or when the LD_BREADTH environment variable is in effect, termination routines were called in load order.

Although this initialization and termination calling sequence seems quite straightforward, be careful about placing too much emphasis on this sequence, as the ordering of objects can be affected by both shared object and application development (see "Dependency Ordering" for more details).


Note -

Any .init or .fini sections within the dynamic executable are called from the application itself by the process start-up and termination mechanism supplied by the compiler driver. The dynamic executable's .init section is called last, after all its dependencies .init sections are executed. The dynamic executable's .fini section is called first, before its dependencies .fini sections are executed.