GCC cxa atexit
From OpenOffice.org Wiki
[The title of this page should have been “GCC __cxa_atexit”; MediaWiki, I love you so much it hurts.]
The thing with GCC --enable-__cxa_atexit appears to be as follows:
- Section 3.3.5 DSO Object Destruction API of the Itanium C++ ABI (at least in revision 1.86; despite its name, this is the ABI GCC generally uses for quite a while now) defines
__cxa_atexit, to register static object destructors andatexithandlers. - On Linux,
__cxa_atexitis available at least since glibc 2.2.4. - At least until GCC 4.0.3, if GCC is not explicitly configured with
--enable-__cxa_atexit, it does not use__cxa_atexitto register static object destructors (but at least on Linux with a glibc that has__cxa_atexit, it nonetheless does use it to registeratexithandlers). - At least since GCC 4.2, GCC no longer needs to be explicitly configured with
--enable-__cxa_atexit—whether or not__cxa_atexitis used to register static object destructors is apparently decided based on the available features of the system. - If GCC does not use
__cxa_atexitto register static object destructors, it violates the C++ Standard in that the relative order of calls of static object destructors andatexithandlers (from within a single run-time object) is wrong (the below code issues two lines offfollowed by two lines of~Cin such a case). Conversely, if GCC does use__cxa_atexitto register static object destructors, it conforms to the C++ Standard in that the relative order of the calls of static object destructors andatexithandlers (from within a single run-time object) is correct (the below code issues two sets of lines~Candfin such a case). - In any event, GCC calls static object destructors and
atexithandlers from a shared object during its finaldlclosecall, or duringexit(if there is no finaldlclosecall). (The C++ Standard would require that static object destructors andatexithandlers are called duringexit, but does not cater for the needs of shared objects.) - The (slightly patched) GCC 3.4.1 used in the Sun Hamburg
setsolarenvironment is configured without--enable-__cxa_atexit(and thus does not use__cxa_atexitto register static object destructors), although the OOo baseline would allow otherwise. (The reason appears to be unknown, it is probably simply that nobody knew the swith needed to be set explicitly.)
Some test code:
-- Makefile
all: main dl.so
main: main.cc
g++ -o $@ -ldl $^
dl.so: dl.cc
g++ -shared -o $@ $^
-- main.cc
#include <cstdlib>
#include <iostream>
#include <dlfcn.h>
int main() {
void * h = dlopen("./dl.so", RTLD_LOCAL | RTLD_LAZY);
if (h == NULL) std::abort();
std::cout << "before dlclose\n";
if (dlclose(h) != 0) std::abort();
std::cout << "before exit\n";
}
-- dl.cc
#include <cstdlib>
#include <iostream>
extern "C" void f() { std::cout << "f\n"; }
struct C {
C() { if (std::atexit(&f) != 0) std::abort(); }
~C() { std::cout << "~C\n"; }
};
static C s1, s2;

