6

I have encountered a strange problems with exceptions using mingw and managed to cut it down to the following example:

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

void test(int a) {
    if (a < 0) {
        throw std::ios_base::failure("a < 0");
    }
}
void test_file(std::string const & fName)
{
    std::ifstream inF(fName.c_str(), std::fstream::in);
    if (!inF) {
        cout << "file error -> throwing exception" << endl;
        throw ios_base::failure("could not open input file '" + fName + "'");
    }
}

int main()
{
    try { test(-5); }
    catch(std::exception& e) {
        cerr << "Exception caught: " << e.what() << " .. continue anyway" <<endl;
    }

    try { test_file("file-that-does-not-exist"); }
    catch(std::exception& e) {
        cerr << "Exception caught: " << e.what() << endl;
        exit(EXIT_FAILURE);
    }
    return EXIT_SUCCESS;
}

The first exception is caught, but the second one does not, so I get the nice Windows error-box informing me that my application has stopped working :-( The full command-line output is:

Exception caught: a < 0 .. continue anyway
file error -> throwing exception

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

The same happen also with other exceptions (like std::runtime_error).

Am I doing something wrong, or is the problem somewhere else?

System info: Windows 7 x64, latest mingw32 (re-installed yesterday using mingw-get from mingw.org).

Thanks a lot in advance.
Michal

Michal Kaut
  • 1,421
  • 1
  • 14
  • 25
  • More details: I found that my IDE (Code::Blocks) uses linker option "-static-libgcc". When I remove it, it works as expected. This really looks like a bug to me.. Any reason to (not) use this option, in general? – Michal Kaut Oct 14 '11 at 09:48
  • 3
    **Update**: The code works if compiled as `g++ -static-libgcc -static-libstdc++ main.cpp` or simply `g++ main.cpp`. The only version that does not work is `g++ -static-libgcc main.cpp`---which is set up in my IDE ;-) Is it a bug? And, more importantly, are there any reason for choosing on of the first two over the other one? – Michal Kaut Oct 14 '11 at 10:52
  • @ Michal: plausible bug. It would be a bug in Code::Blocks then (failure to deduce c++ specific compiler flags) – sehe Oct 14 '11 at 11:24
  • @ sehe: what you are saying is that `-static-libgcc` is not supposed to work without `-static-libstdc++` for C++ code? I did not know that (obviously). – Michal Kaut Oct 14 '11 at 11:48

3 Answers3

2

FWIW, on XP SP3 with MingW:

Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.4.0/configure --prefix=/mingw --build=mingw32 --enable-languages=c,ada,c++,fortran,objc,obj-c++ --disable-nls --disable-win32-registry --disable-werror --enable-threads --disable-symvers --enable-cxx-flags='-fno-function-sections -fno-data-sections' --enable-fully-dynamic-string --enable-libgomp --enable-version-specific-runtime-libs --enable-sjlj-exceptions --with-pkgversion='TDM-1 mingw32' --with-bugurl=http://www.tdragon.net/recentgcc/bugs.php
Thread model: win32
gcc version 4.4.0 (TDM-1 mingw32)

Results in a.exe:

    ntdll.dll => /cygdrive/c/WINDOWS/system32/ntdll.dll (0x7c900000)
    kernel32.dll => /cygdrive/c/WINDOWS/system32/kernel32.dll (0x7c800000)
    msvcrt.dll => /cygdrive/c/WINDOWS/system32/msvcrt.dll (0x77c10000)

Output

Exception caught: a < 0 .. continue anyway
file error -> throwing exception
Exception caught: could not open input file 'file-that-does-not-exist'

So this is soft evidence pointing in the direction of

  • library incompatibility
  • environmental differences
  • bug (?) in your version of MingW
sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    What version of TDM - SJLJ or DW2 exception unwinding? As far as I know, the 'official' mingw uses DW2 (since gcc 4.4), while TDM offers both and recommends SJLJ as the default choice.. – Michal Kaut Oct 14 '11 at 09:35
  • 1
    SJLJ (as shown in the answer `--enable-sjlj-exceptions` but also verified with `objdump.exe a.exe -s -x| egrep -i 'tdm|sjlj|dwarf|dw2'`) – sehe Oct 14 '11 at 09:40
  • Just out of interest - could you try to compile it with `-static-libgcc`? (See my comment above for reasons why.) – Michal Kaut Oct 14 '11 at 09:57
  • Just did, no problem for me. HOWEVER: when using **cygwin g++** with `-static-libgcc` it _does_ crash (it runs ok without the flag) (but you'd get a whole differen output to `ldd`.) Are you mixing up compiler installations? – sehe Oct 14 '11 at 10:00
  • I have only one compiler installed, gcc that comes with mingw (no cygwin) - so no, I am not mixing compilers. However, I have found a possible cause of the bug, see my update of the original post above. – Michal Kaut Oct 14 '11 at 10:56
  • Ha. thanks for the update. Feel free to [asnwer your own question](http://meta.stackexchange.com/questions/17845/etiquette-for-answering-your-own-question) – sehe Oct 14 '11 at 11:25
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4263/discussion-between-sehe-and-michal-kaut) – sehe Oct 14 '11 at 11:54
1

No, I don't think you're doing anything wrong there, this is pretty standard and works quite well under Linux.

I would suggest raising a query with the MinGW people. Even if it's not a bug, they should be able to tell you what's going on.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

I'm also having a problem with this (6 years later), except mine is found with MSYS2, cmake/ninja/mingw32 on windows 7:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.6)
project(FailedExceptions )
add_executable(FailedExceptions  main.cpp foo.c)

Output:

$ cmake .. -GNinja
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- Check for working C compiler: C:/msys64/mingw32/bin/cc.exe -- works
-- Check for working CXX compiler: C:/msys64/mingw32/bin/c++.exe -- works
-- Configuring done
-- Generating done
-- Build files have been written to: C:/msys64/home/sferguson/src/vis/build

$ ninja -v
[1/3] C:\msys64\mingw32\bin\cc.exe    -MD -MT CMakeFiles/FailedExceptions.dir/PortDescription.c.obj -MF CMakeFiles\FailedExceptions.dir\PortDescription.c.obj.d -o CMakeFiles/FailedExceptions.dir/PortDescription.c.obj   -c ../PortDescription.c
[2/3] C:\msys64\mingw32\bin\c++.exe     -MD -MT CMakeFiles/FailedExceptions.dir/main.cpp.obj -MF CMakeFiles\FailedExceptions.dir\main.cpp.obj.d -o CMakeFiles/FailedExceptions.dir/main.cpp.obj -c ../main.cpp
[3/3] cmd.exe /C "cd . && C:\msys64\mingw32\bin\c++.exe    CMakeFiles/FailedExceptions.dir/main.cpp.obj CMakeFiles/FailedExceptions.dir/PortDescription.c.obj  -o FailedExceptions.exe -Wl,--major-image-version,0,--minor-image-version,0  -lgcc_eh -lgcc_eh -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."

$ ./FailedExceptions.exe
Exception caught: a < 0: iostream error
file error -> throwing exception

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

The only catch is that I also need to link some (any) c file, even if I don't use anything it provides. In this case I did it with foo.c:

int foo() { return 0; }
Stewart
  • 4,356
  • 2
  • 27
  • 59