The dynamic objects in a process come from several sources:
- The executable itself
- Any libraries it requires (
DT_NEEDEDfor ELF) - Libraries loaded explicitly (
dlopenor similar) - Any libraries required by such explicit loads
They can be unloaded explicitly (dlclose) or implicitly when the process exits, running their finalization (atexit functions, static-duration destructors in C++, and __attribute__((destructor)) functions) in either case.
What determines the order in which the dynamic objects are initialized and finalized in these various cases? Obviously the last dlclose for a library unloads it immediately, but what about its tree of dependencies (some of which might also be dependencies of other loaded libraries)? What if a library is dlopened but then unloaded by exit?
I tend to expect the usual reverse order of initialization, but maybe there's a difference between DT_NEEDED and dlopen since "plugins" are loaded by the latter and might be expected to depend on the executable's data rather than the other way around.