The answer here demonstrates that __attribute__((constructor)) is not called after static initialization, it is called in the declaration order.
Then, what is the purpose of it, if it is not guaranteed to be called when all data is initialized? We could as well have our ((constructor)) code in the Foo constructor.
What I'm looking for is a way to have, in a shared library, a code that will be executed after all static data is initialized and static constructors are called. I saw people recommending __attribute__((constructor)) as a replacement for DllMain; as we can see this is wrong, because some static data may still be not initialized.
Of course in single file (compilation unit) we could arrange statics. But in a typical program there's a lot of files. Is there a way to guarantee that ((constructor)) in one file will be definitely called after all other statics in a shared library are initialized?
If I put a file with static initialization (constructor, object, etc) to the end of the gcc command line:
g++ -shared -fPIC source1.o source2.o MyLastInitChance.o
are this file's static constructors guaranteed to be called last? I experimented and when I change order of source files, printfs' order is changed; but is it specified somewhere and guaranteed to be the same across compilation systems/computers?
For example, a quote:
At link time, the gcc driver places crtbegin.o immediately before all the relocatable files and crtend.o immediately after all the relocatable files. ©
From what I understand the quote above implies that order of .o files passed to the linker defines order of the static initialization. Am I correct?
Another interesting possible solution, maybe, is to write a GCC plugin that adjusts static initialization (e.g. adds code to .ctors section, etc). But this is just an idea that maybe someone can extend.
One more possible solution is presented here. In short, an external post-build tool can be used to reorder .ctors entries in the executable file (library). But I'm not an expert in ELF format; I wonder if this is possible and easy enough to tweak .so files in this way.
What I'm interested in is solving a particular problem, or proving that it is impossible to solve (at least why the solutions above would not work).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With