32

In *nix .so libraries, is there an entry point that's invoked by the system when the library is loaded and unloaded?

On a more practical note: if the .so was written in C++ and it contains global objects with constructors and destructors, and it's loaded from a language that has no notion of construction/destruction, are the global objects properly constructed/destructed?

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281

3 Answers3

24

You can use the __attribute__((constructor)) and __attribute__((destructor)) to execute code on load and unload of the shared library.

doron
  • 27,972
  • 12
  • 65
  • 103
  • From GNU GCC manual: "_However, at present, the order in which constructors for C++ objects with static storage duration and functions decorated with attribute constructor are invoked is unspecified._" While DllMain is guaranteed to run when static storage objects are already initialized. This guarantee is important if you want to use the static objects from within the library setup/teardown functions. – Alex Che Jul 02 '19 at 11:03
  • 1
    You can look [here](https://stackoverflow.com/q/22763945/23715) for the difference. – Alex Che Jul 02 '19 at 11:14
21
  1. No, there is no equivalent to DllMain.

  2. For JNI libraries, e.g. on Android, there may be a special entry JNI_OnLoad which is intended to fill JNI function table.

  3. GCC defines special attribute constructor to allow some code to run on shared library load.

  4. C++ guarantees that the constructors for global and static objects will be performed, no matter if the code that loaded the .so was aware of these classes, or had notion of construction.

    Same holds for destructors, but there may be unhappy circumstances when at least some destructors have no chance to run - e.g. when there is a sigfault and exceptions are disabled.

Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • 1
    By this logic, every constructor is kinda equivalent to DllMain :) – Seva Alekseyev Sep 17 '12 at 17:23
  • 3
    Not exactly. DllMain runs for each thread attached - there is nothing to resemble this in Linux. And, as answered here by James Kanze, global object constructors are run by the runtime library not through the DllMain mechanism. – Alex Cohn Sep 17 '12 at 17:29
  • But then there must be something OS-level that invokes the RTL's global-init sequence... – Seva Alekseyev Sep 17 '12 at 19:59
  • @SevaAlekseyev: yes, but the global-init sequence doesn't have to be overloadable, nor does it have to execute any non-constructor functions (such as `DllMain`) inside the library. – Mooing Duck Mar 22 '13 at 18:33
  • I fail to see any difference (except semantic) between a constructor and a non-constructor :) – Seva Alekseyev Mar 22 '13 at 18:59
  • See http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html - the constructor function attribute has nothing to do with C++ constructors. – Alex Cohn Mar 22 '13 at 19:14
  • 2
    @SevaAlekseyev: the contract is that functions with `__attribute__((constructor))` will execute before `dlopen()` returns. – Alex Cohn Apr 07 '13 at 18:18
6

The technique used is a little different, but the construction/destruction of global objects is more or less built into the dynamic loader. (Even under Windows, there's no need to go through DllMain. The global objects will be constructed/destructed correctly anyway.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329