Linking dynamic libraries and initializing variables
Posted August 27, 2011 at 15:14 by wyldckat
Updated July 10, 2016 at 17:22 by wyldckat (added more links...)
Updated July 10, 2016 at 17:22 by wyldckat (added more links...)
This blog post is an effort to document the search for solutions for loading dynamically linked libraries and initializing their objects in the desired order. With me, it all started with this bug report: http://bugs.openfoam.org/view.php?id=236
Basically, OpenFOAM initializes debug values right after loading all of the necessary libraries. These debug values are read from the global controlDict files (see $WM_PROJECT_DIR/etc/controlDict in your own OpenFOAM installation, or at the git repo) during loading time, even before the main function of the calling process is executed. The code that I'm talking about is this one:
The debugSwitch method will load the desired variable-value pair from controlDict. So far so good... except when there is a flaw in the text code in controlDict, which triggers the error messaging system... which has been initialized yet!
This has been fixed as of OpenFOAM 2.0.x, as documented here, but this is a problem for past versions. Why you ask? Because as soon as the global controlDict is damaged, all applications would crash with a segmentation fault, due to an untimely access to an uninitialized object.
As indicated in the previous paragraph, this bug is fixed now. The solution so far has been to avoid accessing the uninitialized object, but the doubt still remains on how to force the proper order of loading and initialization. On that bug report there are already a lot of information, so I'm just going to list here the findings I've tried to make since then, in order to keep that bug report more centric on the issue itself.
So, here's the list:
Conclusions so far:
Basically, OpenFOAM initializes debug values right after loading all of the necessary libraries. These debug values are read from the global controlDict files (see $WM_PROJECT_DIR/etc/controlDict in your own OpenFOAM installation, or at the git repo) during loading time, even before the main function of the calling process is executed. The code that I'm talking about is this one:
Code:
//- Define the debug information, lookup as \a Name #define defineDebugSwitchWithName(Type, Name, DebugSwitch) \ int Type::debug(::Foam::debug::debugSwitch(Name, DebugSwitch))
This has been fixed as of OpenFOAM 2.0.x, as documented here, but this is a problem for past versions. Why you ask? Because as soon as the global controlDict is damaged, all applications would crash with a segmentation fault, due to an untimely access to an uninitialized object.
As indicated in the previous paragraph, this bug is fixed now. The solution so far has been to avoid accessing the uninitialized object, but the doubt still remains on how to force the proper order of loading and initialization. On that bug report there are already a lot of information, so I'm just going to list here the findings I've tried to make since then, in order to keep that bug report more centric on the issue itself.
So, here's the list:
- A must read: What's the "static initialization order fiasco"? - check the whole page, since it has a loooot of valuable information.
- Solaris: Initialization & Termination routines in a dynamic object - documents how to force order of the functions to be loaded in a dynamic linked library. Some of those apply to Linux: ld options "-z"
- Another one for Solaris: Resolving the Initialization Order Problem
- A detailed explanation on how ELF works: Acronyms relevant to Executable and Linkable Format (ELF)
- How to have a loading/unloading area in each dynamic library, for Linux and Windows: Implementing DllMain in a linux shared library
- More information about the loading/unloading area for Linux: Program Library HOWTO - Miscellaneous
- Article about "Dynamic Linking in Linux and Windows": part one and part two.
- IBM's C++ compiler xlC: Order of object initialization across libraries
- Setting the initialization order within a single library, at least for GNU Gcc: C++-Specific Variable, Function, and Type Attributes
Conclusions so far:
- Hacking the loading/initialization order is probably a must. This means that for each platform+compiler, there will be different solutions, if any.
- Using "namespace std" for the error management code seemed like a good solution, since there seems to be a careful selection on ld/gcc. But embedding it directly in libOpenFOAM doesn't seem to help things.
- What would help the initialization order would be to separate these more basic (debug) functions to a separate and somewhat independent library. This would make it easier to enforce the initialization order, since this library would have a higher probability of being put closer to libc, pthreads and Open-MPI, therefore being initialized on time.
Total Comments 1
Comments
-
I haven't confirmed this yet, but several months ago, this might have been somewhat fixed in OpenFOAM 3... namely in these commits:
Posted June 25, 2017 at 12:34 by wyldckat