On Aug 5, 2012, at 1:09 PM, David Edelsohn wrote: > On Sun, Aug 5, 2012 at 9:56 AM, Perry Smith <pedz...@gmail.com> wrote: > >> I was planning on exploring when _GLOBAL__FD was called today. I >> need to figure out when gcc puts the call to the dtor in _GLOBAL__FD >> path rather than in the atexit path. The net implies that "static" uses >> atexit while a global non-static uses _GLOBAL__FD >> >> I'm also exploring what it would take to port a version of GNU's >> __cxa_atexit to AIX. I think after I figure out when various dtors >> get called, I should be able to figure out if / how to do that. >> >> Part of my confusion / concern is "why have two methods?" >> Does the spec say that dtors much be called at different times? > > Destructors are added to _GLOBAL__FD by collect2 at link time. It > scans the object files for destructor functions, sorts them by > priority and creates a function connected to _GLOBAL__FD to call them. > Collect2 performs the same grouping for constructors, creates a > function and connects it to _GLOBAL__FI. The uniquely named functions > are added to the AIX linker command line as arguments to the > -binitfini option to establish them as initializer/finalizer functions > for the shared object. > > AIX does not have a ctor/dtor or init/fini section in object files, > nor _cxa_atexit. > > AIX dlclose() should call AIX terminateAndUnload() service that will > call the fini routine registered by -binitfini. If something else in > GCC is trying to register the termination function for systems without > _cxa_atexit() using atexit(), it probably is conflicting and trying to > run the destructors twice. > > Another difference between AIX and SVR4 is AIX invokes init and fini > functions for multiple, dependent shared objects breadth first, while > SVR4 invokes them depth first based on library dependencies. There is > an old Bugzilla entry with a proposal to push init functions onto a > stack as they are seen when libraries are loaded and then run them in > SVR4 dependency order.
Thank you both for helping. I understand when atexit is used. I believe the _GLOBAL__FD method could be used instead and would be more correct but it somehow needs to be conditionalized. To get the atexit to be used, you need a function that returns a static that is declared inside the function. In my code below, this is "func". The function registered with atexit is called tcf_0 (I'm sure that would increment if there are more than one). I mention that hoping it might help in tracking down where it is being created. There are other parts to this program that I left because, to me, it was interesting when atexit is called and all the places where it is not called. I call the program x1.cpp. x1 with no argument does not create "func". x1 with an argument does. Note that if func is not created, the dtor is not called (which seems obvoius but that is where the difficulty is going to come from). My thoughts on how to solve this would call tcf_0 from the _GLOBAL_FD and have tcf_0 check a flag. If not set, it does nothing. In the special ctor where atexit is now being called, just set that flag instead of calling atexit. Here is the program: #include <iostream> using namespace std; class foo { private: const char *name; void mess(const char *s) { cout << s << " " << name << endl; } public: foo(const char *s) { name = s; mess("ctor"); } ~foo() { mess("dtor"); } }; class bar { static foo surf; }; foo bar::surf("bar"); foo g("global"); static foo s("static"); foo& func() { static foo val("func"); return val; } int main (int argc, char *argv[]) { cout << "Hello World!" << endl; foo a("auto"); if (argc > 1) foo &f = func(); cout << "Good Bye World!" << endl; return 0; } Output with x1 called with no argument: ctor bar ctor global ctor static Hello World! ctor auto Good Bye World! dtor auto dtor static dtor global dtor bar Output with x1 called with an argument: ctor bar ctor global ctor static Hello World! ctor auto ctor func << atexit called just after this prints. Good Bye World! dtor auto dtor func dtor static dtor global dtor bar I'm happy to create a bug report if anyone wants me to. Thank you again, Perry