Created attachment 26821 [details] Short exemplary code showing the problem Attached file compiles flawlessly on 4.7.0, but the output binary segfaults. Works fine in 4.6.2 though (as expected). Looks like a serious regression. g++-4.7 (GCC) 4.7.0 20120304 (prerelease) built on debian wheezy x64 with: --enable-languages=c,c++ --prefix=/opt/gcc-4.7 --program-suffix=-4.7 svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@184878
looks like .init_array vs. .ctors problem.
you should specify explicit initialization order to avoid gpf, e.g.: static std::map<int, int> m __attribute__((init_priority(101))); static void insert() __attribute__((constructor(102)));
Thanks for solution, but... Isn't such order obvious or isn't it at least the most widely used one? I mean that by default static data initialization should precede constructor-functions, no? It worked in gcc 4.6 and is there any good reason to break it?
I think it's undefined what you relied upon.
Resolving as invalid based on comment #3. The manual does seem to suggest that this should work: "The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects (see C++ Attributes)." Let me add a blurb to make clear that the order between C++ ctors and functions declared attribute constructor is unspecified. Blurb posted for review: https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00863.html
I don't think this is undefined; it seems natural for these functions to be ordered with a translation unit along with dynamic initialization of non-local variables. So for --- extern "C" int printf (const char *, ...); struct A { A() { printf ("A\n"); } } a; static void B() __attribute__((constructor)); static void B() { printf ("B\n"); } struct C { C() { printf ("C\n"); } } c; int main() {} --- I would expect A B C, and gcc currently outputs B A C. Instead of emitting constructor functions directly into .init_array as we do now, we should remember them and call them from __static_initialization_and_destruction_0. Note that 4.6 gave the differently wrong A C B, due to running .init_array in the opposite order, so this isn't really a regression.
Author: msebor Date: Mon Mar 20 18:33:31 2017 New Revision: 246288 URL: https://gcc.gnu.org/viewcvs?rev=246288&root=gcc&view=rev Log: PR c++/52477 - Wrong initialization order __attribute__((constructor)) vs static data access * doc/extend.texi (attribute constructor): Document present limitation. Modified: trunk/gcc/ChangeLog trunk/gcc/doc/extend.texi
r246288 updates the manual for GCC 7 and documents the limitation (as per commetn #6) but the issue itself remains unresolved.
*** Bug 81337 has been marked as a duplicate of this bug. ***
I will try to look at it.
(In reply to Martin Liška from comment #10) > I will try to look at it. Do you see a chance to look at this before GCC 8? Thanks. Rainer
(In reply to Rainer Orth from comment #11) > (In reply to Martin Liška from comment #10) > > I will try to look at it. > > Do you see a chance to look at this before GCC 8? > > Thanks. > Rainer I'm sorry but probably after the release in next stage1.
Well, after we documented that can we simply close it?
(In reply to Martin Liška from comment #13) > Well, after we documented that can we simply close it? Quite the contrary: that documents a *current* limitation! See Jason's comment #6 for what needs to happen.
(In reply to Rainer Orth from comment #14) > (In reply to Martin Liška from comment #13) > > Well, after we documented that can we simply close it? > > Quite the contrary: that documents a *current* limitation! See Jason's > comment #6 > for what needs to happen. I see, thanks for clarification.
Leaving for now..
(In reply to Jason Merrill from comment #6) I was looking into this area trying to diagnose/solve a testsuite fail on Darwin (see pr91087). > > I would expect A B C, and gcc currently outputs B A C. I assume that's because the SysV ABI says: "Termination functions specified by users via the atexit mechanism must be executed before any termination functions of shared objects.” and, therefore (for PIC at least) we would get incorrect nesting of CTORs and DTORs if the __attribute__((constructor)) was not run first. > Instead of emitting > constructor functions directly into .init_array as we do now, we should > remember them and call them from __static_initialization_and_destruction_0. Implementing this would probably also provide a workaround for the Darwin bug (by avoiding the use of special sections for the attributed ctor/dtors. Is there any specification that demands a specific section for the __attribute__((constructor/destructor))s?