I am writing a Windows DLL in C++. This library has only C interface and uses only standard Windows libraries which also have C interface. Therefore it seems me safe to statically link all C++ libraries into the library because I am not dependent on C++ ABI version when using C interfaces only.
Unfortunately when I compile my library with -static-stdc++ -static-libgcc
, my library stops handling exceptions and when some exception is thrown, the DLL calls its statically linked _Unwind_RaiseException
function which aborts the whole application.
I thought it could be a corrupted libgtcc.a
so I tried to update my compiler. But the result is the same with both MinGW 4.8 and MinGW 6.3.
Please is anybody able to explain me what is really happening here?
Klasyc
Thanks RastyX for that simple example in his answer. After some research I found out that the application crashes when I compile DLL part with
-static-libgcc
and application part without this switch (both parts compiled with the same g++).Also thanks to Ripi2 for TDM-GCC suggestion. I tried both SJLJ and DWARF-2 exception handling and both work.
To conclude it, it seems MinGW's libgcc does not like when it is instantiated more than once per process. In my case I use one its copy in DLL (linked statically) and one its copy in the application and this probably breaks the exception handling.
On the other hand TDM-GCC focuses on static linking of the basic libraries as its web page says and therefore produces binaries that depend only on Windows libraries even without
-static-stdc++ -static-libgcc
command line switches (this is what I want). Also the exception handling works here, so changing of the toolchain is the right way for me.Are you handling all exceptions inside the DLL? If any exception "leaks" outside a function with a C calling convention, it will crash the application.
I am having no problems with C++ exceptions under MinGW x86_64-5.3.0-win32-seh-rt_v4-rev0 and mingw32 4.8.1 dwarf2 with a static libstdc++/libgcc.
DLL source (
dll.cpp
):Application source (
app.c
):Compile it:
g++ -O2 -static-libgcc -static-libstdc++ -shared -Wl,--out-implib=dtest.lib -s -o dtest.dll dll.cpp
g++ -O2 -static-libgcc -static-libstdc++ -L. -s -o app app.c -ldtest
Output:
To answer your comment "Why do I need compiler with SEH support? I thought SEH allows me to catch Windows exceptions" - on Windows, SEH is the de-facto standard for all exceptions, including C++ exceptions (when compiled with Visual C++). MinGW has different implementations for C++ exceptions (SEH, SJLJ and DWARF), however SEH is the only mechanism with zero overhead, so if it's available you really should prefer it over SJLJ and DWARF.