Help save net neutrality! Learn more.
Close

#369 Fully optimized template code causes crash in Win32 built executable

v1.0 (example)
open
nobody
5
2015-02-08
2013-12-09
No

The attached preprocessed file (from a regression test for std::array with multiple dimensions) crashes the resulting executable in startup code with an unhandled exception when built with full optimization (-O3) for 32bit windows. When built with reduced optimization (-O2) or for 64bit windows the code runs ok.
The exact compile commands were:

g++ -std=c++0x -O2 -Wno-deprecated -mthreads -mtune=pentiumpro -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -Wno-unknown-pragmas  -c -o .obj/client.o client.i

g++ -std=c++0x -O3 -Wno-deprecated -mthreads -mtune=pentiumpro -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -Wno-unknown-pragmas  -c -o .obj/client.o client.i

We are using a GCC 4.8.2 version from the mingw-builds section:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=c:/mingw64/bin/../libexec/gcc/i686-w64-mingw32/4.8.2/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../../../src/gcc-4.8.2/configure --host=i686-w64-mingw32 --build=i686-w64-mingw32 --target=i686-w64-mingw32 --prefix=/mingw32 --with-sysroot=/tmp/i686-482-win32-dwarf-rt_v3-r0/mingw32 --enable-shared --enable-static --disable-multilib --enable-languages=ada,c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-sjlj-exceptions --with-dwarf2 --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=i686 --with-tune=generic --with-libiconv --with-system-zlib --with-gmp=/tmp/prerequisites/i686-w64-mingw32-static --with-mpfr=/tmp/prerequisites/i686-w64-mingw32-static --with-mpc=/tmp/prerequisites/i686-w64-mingw32-static --with-isl=/tmp/prerequisites/i686-w64-mingw32-static --with-cloog=/tmp/prerequisites/i686-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='rev0, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/tmp/i686-482-win32-dwarf-rt_v3-r0/mingw32/opt/include -I/tmp/prerequisites/i686-zlib-static/include -I/tmp/prerequisites/i686-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/tmp/i686-482-win32-dwarf-rt_v3-r0/mingw32/opt/include -I/tmp/prerequisites/i686-zlib-static/include -I/tmp/prerequisites/i686-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/tmp/i686-482-win32-dwarf-rt_v3-r0/mingw32/opt/lib -L/tmp/prerequisites/i686-zlib-static/lib -L/tmp/prerequisites/i686-w64-mingw32-static/lib -Wl,--large-address-aware'
Thread model: win32
gcc version 4.8.2 (rev0, Built by MinGW-W64 project)
1 Attachments

Discussion

  • niXman

    niXman - 2013-12-09

    Please attaching the minimalistic code sample that reproduces this error.

     
  • Kai Tietz

    Kai Tietz - 2013-12-09

    Yes, a reduced testcase might be helpful here. My bets are going here for out-stack-memory exception. What exception you've got? In gdb you are able to see uncaught exceptions.

    Have you tried to raise stack-limit by -Wl,--stack,<size>?

    Kai

    Side-note: I see within code that within templates you are passing arguments a local copies, but in mainly cases a constant refrence seems to me more efficient.

     
    • Martin Corino

      Martin Corino - 2013-12-09

      Unfortunately I've not been able to use GDB from that build because that seems to have a problem as well. It complains about not being able to find an entry point in the libstdc++ shared library when trying to run the application from GDB.

       
    • Martin Corino

      Martin Corino - 2013-12-09

      I'll try the -Wl,--stack option. I hadn't really considered the size of these arrays yet :-(

      Yes, we noticed the copies as well (this test was originally made by a novice programmer) but rather than optimizing the problem away we thought best to first see if this might be a genuine optimization bug.

       
  • Martin Corino

    Martin Corino - 2013-12-09

    Unfortunately that's not really an option. This regression test is part of a very large distributed middleware framework and would need far too large a code/binary package to upload and I have not been able to strip the test down to a version without the framework dependency and still exhibit the problem.
    I know the code produced for the preprocessed compile unit I attached is the culprit because relinking with either the fully optimized version or the less optimized version reproduces failure or success.

     
  • niXman

    niXman - 2013-12-09

    [offtopic]
    1. arguments to eqArray() functions is better to pass using a constant reference.
    2. std::array<> of POD types is better to compare using std::memcmp(), like this: http://pastebin.com/3MZ8eNfS
    [/offtopic]

     
    Last edit: niXman 2013-12-09
    • Martin Corino

      Martin Corino - 2013-12-09

      All true. Regarding the memcmp; the objective here was not performance though but coding efficiency; one set of template functions to compare a whole range of array types also including non-pod types.

       
      • niXman

        niXman - 2013-12-09

        How the passing arguments by value and elementwise compare increase the coding efficiency?

         
        Last edit: niXman 2013-12-09
        • Martin Corino

          Martin Corino - 2013-12-09

          I was referring only to the memcmp remark, not the passing by value. Memcmp does not work for non-pod types which we are also using at some point. With element wise comparison the function templates also work for them.

           
          • niXman

            niXman - 2013-12-09

            In the example to which I gave a link, this is considered.
            Please, look at the code that I gave a link.

            P.S.
            As a variant - try to change the code so that std::array<> passed by reference, and let us know if the error remains.

             
            • Martin Corino

              Martin Corino - 2013-12-09

              Thank you both a lot for the replies. The problem turned out to indeed be a stack problem.
              To be complete and because I have not yet been able to find the answer elsewhere; could you tell me what the default stack size of MingW built Win32 executables is?

               
  • niXman

    niXman - 2013-12-09

    In any case, without a minimum example reproducing the error, it is meaningless to talk about anything...

     
  • Kai Tietz

    Kai Tietz - 2013-12-09

    For 32-bit stack is 0x200000 bytes in maximum. You can see this limit by using 'objdump -x <executable>' and check for line SizeOfStackReserve.

     

Log in to post a comment.