[Bug target/33704] AIX runs c++ constructors in incorrect order
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704 David Edelsohn changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #24 from David Edelsohn --- Fixed.
[Bug target/33704] AIX runs c++ constructors in incorrect order
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704 --- Comment #23 from David Edelsohn --- Author: dje Date: Sat Nov 23 15:38:07 2013 New Revision: 205309 URL: http://gcc.gnu.org/viewcvs?rev=205309&root=gcc&view=rev Log: libgcc: PR target/33704 * config/rs6000/aixinitfini.c: New file. * config/rs6000/t-aix-cxa (LIB2ADD_ST): Add aixinitfini.c. * config/rs6000/libgcc-aix-cxa.ver (GCC_4.9): Add libgcc initfini symbols. gcc: PR target/33704 * config/rs6000/aix.h (COLLECT_SHARED_INIT_FUNC): Define. (COLLECT_SHARED_FINI_FUNC): Define. * collect2.c (aix_shared_initname): Declare. (aix_shared_fininame): Declare. (symkind): Add SYM_AIXI and SYM_AIXD. (scanfilter_masks): Add SCAN_AIXI and SCAN_AIXD. (struct names special): Add GLOBAL__AIXI_ and GLOBAL__AIXD_. (aixlazy_flag): Parse. (extract_init_priority): SYM_AIXI and SYM_AIXD have highest priority. (scan_prog_file, COFF): Handle SYM_AIXI and SYM_AIXD. Added: trunk/libgcc/config/rs6000/aixinitfini.c Modified: trunk/gcc/ChangeLog trunk/gcc/collect2.c trunk/gcc/config/rs6000/aix.h trunk/libgcc/ChangeLog trunk/libgcc/config/rs6000/libgcc-aix-cxa.ver trunk/libgcc/config/rs6000/t-aix-cxa
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #22 from bkoz at gcc dot gnu dot org 2007-10-19 02:00 --- > I believe there are other functions in libstdc++ that depend on initialization > order. I do not have specifics. Perhaps: FAIL: 27_io/objects/char/6.cc execution test FAIL: 27_io/objects/wchar_t/6.cc execution test FAIL: ext/mt_allocator/check_new.cc execution test FAIL: ext/pool_allocator/check_new.cc execution test from: http://gcc.gnu.org/ml/gcc-testresults/2007-10/msg00820.html These are the ones I would suspect might change. FWIW, I agree 100% with Wolfgang's venting in #8, #10. Correct __cxa_atexit behavior is essential. -benjamin -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #21 from ajd at gentrack dot com 2007-10-19 01:44 --- Created an attachment (id=14372) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14372&action=view) support -blazy, add option to disable I suggest exportinitfini_flag is enabled by default or atleast for the build of libstdc++.a and libgcc_s.a. It should have minimal impact/risk. initdependents_flag has risk/impact attached. You may want to reverse the default. My case for having it on by default: To use exceptions within global constructors a module needs to be linked with initdependents_flag enabled. I believe there are other functions in libstdc++ that depend on initialization order. I do not have specifics. Assuming AIX was the only OS that works this way, it allows removal of these types of workarounds: http://gcc.gnu.org/ml/libstdc++/2001-01/msg00369.html -- ajd at gentrack dot com changed: What|Removed |Added Attachment #14327|0 |1 is obsolete|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #20 from dje at gcc dot gnu dot org 2007-10-18 00:48 --- Yes, effectively -blazy, because of AIX's loader semantics. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #19 from ajd at gentrack dot com 2007-10-14 21:39 --- (In reply to comment #18) > Do you plan to support lazy binding as well? Do you mean -blazy? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #18 from dje at gcc dot gnu dot org 2007-10-12 12:56 --- I think your patch would be okay as an option. Do you plan to support lazy binding as well? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #17 from ajd at gentrack dot com 2007-10-10 04:04 --- (In reply to comment #16) > lib1.a depends on lib2.a > main depends on lib1.a, but does not explicitly link with lib2.a main initializes what it is explicitly linked against. lib1 initializes lib2 before it initializes itself. -- See attached test_init_order.cpp: $ # -- create lib2 $ g++ -shared -o lib2.a -D LIBNAME=LIB2 test_init_order.cpp $ # -- create lib1 depends on lib2 $ g++ -shared -L. -l2 -o lib1.a -D LIBNAME=LIB1 -DCALLEE=LIB2 test_init_order.cpp $ # -- hide lib2 from main $ mv lib2.a /tmp/lib2.hide $ # -- link main against lib1 $ g++ -L. -l1 -o m -D LIBNAME=main -DCALLEE=LIB1 test_init_order.cpp $ # -- unhide lib2 $ mv /tmp/lib2.hide lib2.a $ ./m LIB2_init LIB1_init main_init main() LIB1() LIB2() main_fini LIB1_fini LIB2_fini $ # -- replace lib1 with a library that doesn't depend on lib2 $ # -- leave main alone $ g++ -shared -o lib1.a -D LIBNAME=LIB1 test_init_order.cpp $ /usr/local/bin/sudo slibclean $ ./m LIB1_init main_init main() LIB1() main_fini LIB1_fini -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #16 from dje at gcc dot gnu dot org 2007-10-10 03:17 --- lib1.a depends on lib2.a main depends on lib1.a, but does not explicitly link with lib2.a Your proposed solution requires that the link of main see all dependent libraries. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #15 from ajd at gentrack dot com 2007-10-09 21:44 --- (In reply to comment #14) > You seem to want to have the main program run the share library constructors. > That's a no-no. And decide at link-time. Double no-no. Do you mind explaining a situation that won't work because of this? The the following work should work as -binitfini is still used: - LDR_PRELOAD - libraries loaded by dlopen at runtime - executables linked by xlc loading libraries compiled by gcc If main was directly linked against lib1.a: - lib1.a can add/remove dependencies against other libraries. - lib1.a can change it's constructors. - lib1.a can be resolved to a completely different library as long as the replacement contains __GLOBAL__FI_lib1. The two situations I can identify that won't work are if the replacement lib1.a was renamed or was compiled by xlc. I can look at resolving these if they're the only problems. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #14 from dje at gcc dot gnu dot org 2007-10-09 21:10 --- You seem to want to have the main program run the share library constructors. That's a no-no. And decide at link-time. Double no-no. You essentially want to behave like a static link. If you look at the discussion from years ago, to solve this correctly one needs to implement a solution at runtime, not link-edit time. At runtime, the constructors need to register themselves instead of running, then the init processing in the main program performs a global sort, and then actually runs the constructors depth-first. Please open the throw failure as a separate PR if it is a separate issue. I cannot tell if you think it is a byproduct of AIX behavior or a separate issue. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #13 from ajd at gentrack dot com 2007-10-09 20:06 --- (In reply to comment #9) > A solution within GCC is very complicated. Have you looked at the suggested patch? If you could point out any concerns/faults, I could have another try at it. XLC has it's own solution implemented within the compiler / support libraries. So it seems the loader behaviour only impacts gcc. It could be seen as a deficiency in the gcc compiler / support libraries. (In reply to comment #11) > The problem *could* be solved in GCC, so it probably is worth retaining the > PR. Should I raise a separate PR for throw_failure.cpp? I lumped them together because I figured it was the same root cause. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #12 from bangerth at dealii dot org 2007-10-09 15:18 --- (In reply to comment #11) > The problem *could* be solved in GCC, so it probably is worth retaining the > PR. OK. > AIX Brand is much more likely to respond to a customer requirement than a > request from within IBM. When the problem affects a sale, IBM will address > it. Fair enough. Sorry to (ab)use you in this regard. W. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #11 from dje at gcc dot gnu dot org 2007-10-09 15:07 --- The problem *could* be solved in GCC, so it probably is worth retaining the PR. AIX Brand is much more likely to respond to a customer requirement than a request from within IBM. When the problem affects a sale, IBM will address it. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #10 from bangerth at dealii dot org 2007-10-09 14:53 --- If it's a request to improve the AIX linker, should we even keep this PR open? David, as a sidenote (because you're at IBM), this is the sort of thing that makes AIX such an unpopular target to do development on. It just surprises me that 10+ years after everyone else had their linker fixed to support proper C++ templates and initialization order, IBM's linker still can't do it. I found porting our 350 kloc template-heavy code to AIX one of the more painful exercises I ever did. That's not your fault, but maybe you can pass it on to someone in charge. Sigh, and sorry for the digression... W. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #9 from dje at gcc dot gnu dot org 2007-10-09 12:50 --- This is a long-standing issue about the way AIX loader behaves. AIX loader implements breadth-first, not depth first. This is a difference from SVR4-based systems. I believe that SVR4 does specify the ordeer. Look about 10 years ago on the mailinglist for a similar discussion. A solution within GCC is very complicated. This really is an enhancement request for AIX itself to make it more compatible with Linux and other SVR4-like operating systems. -- dje at gcc dot gnu dot org changed: What|Removed |Added Severity|normal |enhancement Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Last reconfirmed|-00-00 00:00:00 |2007-10-09 12:50:46 date|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #8 from bangerth at dealii dot org 2007-10-09 03:43 --- (In reply to comment #6) > And the order is still undefined between them, does not matter if it is a > shared library or otherwise. It is true that the standard only talks about the order of initialization within each translation unit. That doesn't make the current PR any less of a valid enhancement request. It's not a coincidence that all the other systems allow this to work -- this is a very useful feature and it would be nice if we could get it to work on AIX as well. W. -- bangerth at dealii dot org changed: What|Removed |Added CC||dje at watson dot ibm dot ||com, bangerth at dealii dot ||org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #7 from ajd at gentrack dot com 2007-10-09 02:43 --- Introduced here: http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00616.html My suggested fix is co-incidentally reversing some of that patch. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #6 from pinskia at gcc dot gnu dot org 2007-10-09 01:59 --- And the order is still undefined between them, does not matter if it is a shared library or otherwise. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #5 from ajd at gentrack dot com 2007-10-09 01:55 --- Please reconsider. This is about initialization order between shared libraries. Not betweeen objects within a library. This works on atleast Linux, Windows, Solaris, HPUX, Tru64. The testcase throw_failure.cpp shows that libgcc/libstdc++ depend on this initialization order. So if the initialization order is really unspecified, then libgcc/libstdc++ have a bug. -- ajd at gentrack dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #4 from ajd at gentrack dot com 2007-10-09 01:50 --- Created an attachment (id=14327) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14327&action=view) suggested solution The attached patch is a suggested solution to this problem. It calls the __GLOBAL__FI_... functions (which call the C++ constructors) of linked libraries before calling the constructors of the current module. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #3 from ajd at gentrack dot com 2007-10-09 01:49 --- Created an attachment (id=14326) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14326&action=view) shows fallout from this (throw does not work in a global constructor as libstdc++ and libgcc_s constructors have not been run). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #2 from ajd at gentrack dot com 2007-10-09 01:48 --- Created an attachment (id=14325) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14325&action=view) testcase shows constructors running in incorrect order Compile like: g++ -shared -o liba1.a -D LIBNAME=LIB1 test_init_order.cpp g++ -shared -L. -la1 -o liba2.a -D LIBNAME=LIB2 -DCALLEE=LIB1 test_init_order.cpp g++ -shared -L. -la2 -o liba3.a -D LIBNAME=LIB3 -DCALLEE=LIB2 test_init_order.cpp g++ -L. -la3 -o m -D LIBNAME=main -DCALLEE=LIB3 test_init_order.cpp Creates libraries dependencies like: m -> LIB3 -> LIB2 -> LIB1 Expected output is: LIB1_init LIB2_init LIB3_init main_init main() LIB3() LIB2() LIB1() main_fini LIB3_fini LIB2_fini LIB1_fini Actual output is: main_init LIB3_init LIB2_init LIB1_init main() LIB3() LIB2() LIB1() LIB1_fini LIB2_fini LIB3_fini main_fini -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704
[Bug target/33704] AIX runs c++ constructors in incorrect order
--- Comment #1 from pinskia at gcc dot gnu dot org 2007-10-09 01:48 --- It is not specificed which order of constructors are run between two different Translation units. -- pinskia at gcc dot gnu dot org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33704