I was not able to reproduce the bug on Linux, so I assume this is a Windows-specific. If an exception is generated inside shared library (DLL), then crosses the DLL-boundary and gets caught in some other module, the std::uncaught_exception will always return wrong (inverted) value from now on. Here's a small test case. The DLL (throw.dll) contains just a single function that throws an exception: throw.cpp ~~~~~~~~~ void do_throw(void) { throw(""); } The test program (test.exe) is linked against throw.dll: test.cpp ~~~~~~~~ #include <exception> #include <iostream> bool b; void do_throw(void); struct UE { ~UE() { b = std::uncaught_exception(); } }; int main(void) { try { do_throw(); } catch (...) { } try { UE ue; throw ""; } catch (...) { } std::cout << "Expecting 'true', got " << (b ? "'true'" : "'false'") << std::endl; { UE ue; } std::cout << "Expecting 'false', got " << (b ? "'true'" : "'false'") << std::endl; return 0; } test.exe produces the following output: C:\TEMP\bug>test.exe Expecting 'true', got 'false' Expecting 'false', got 'true' If we comment out the call to do_throw(), std::uncaught_exception will work as expected. If we put do_throw() in a statically linked module, std::uncaught_exception will work as expected as well.
Created attachment 18275 [details] Test case
(In reply to comment #0) > I was not able to reproduce the bug on Linux, so I assume this is a > Windows-specific. > > If an exception is generated inside shared library (DLL), then crosses the > DLL-boundary and gets caught in some other module, the std::uncaught_exception > will always return wrong (inverted) value from now on. Here's a small test > case. > You need to link against a shared libgcc and a shared libstdc++ for this to work. Shared libgcc is part of standard build now for mingw Shared libstdc++ is close. http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01042.html Danny
I'm linking using g++ driver, so shared libgcc is enabled by default in 4.4.0. I've just tried to enabled shared libstdc++ as described in the Release Notes to the MinGW GCC 4.4.0 release, which made no difference. More over, I modified the test case the following way: I got rid of std::cout in favor of printf(), added -nodefaultlibs option to the linker and specified all the required libraries manually. Now libstdc++ is not linked at all (neither static nor dynamic), the bug is still here. I'll attach the modified test case shortly.
Created attachment 18277 [details] Modified test case (not dependent on libstdc++ at all)
(In reply to comment #3) > I'm linking using g++ driver, so shared libgcc is enabled by default in 4.4.0. > I've just tried to enabled shared libstdc++ as described in the Release Notes > to the MinGW GCC 4.4.0 release, which made no difference. > > More over, I modified the test case the following way: I got rid of std::cout > in favor of printf(), added -nodefaultlibs option to the linker and specified > all the required libraries manually. Now libstdc++ is not linked at all > (neither static nor dynamic), the bug is still here. > I cannot comment on the build of libsdc++.dll in the mingw 4.4.0 release since I have not looked at that source. However, your revised testcase -- linking against a static libsupc++ -- would be expected to fail. We can have only one instance of the eh_globals structure defined in libsupc++/eh_globals.cc. This is accomplished by linking both the .exe and the .dll against a shared libstdc++. Applying Dave Korn's patch mentioned in Comment #2, and linking against libstdc++.dll, I get this with your original testcaase: Expecting 'true', got 'true' Expecting 'false', got 'false'
(In reply to comment #5) > I cannot comment on the build of libsdc++.dll in the mingw 4.4.0 release since > I have not looked at that source. There is a patch file that is shipped along with the mingw 4.4.0 build instructions/script. The patch adds most of the essential things that the Dave Korn's patch does (i.e. __attribute__((dllimport)) decorations and -no-undefined linker option.) I believe the official MinGW binaries were built with that patch applied. Well, there are your E-mail at the top of that patch file... > Applying Dave Korn's patch mentioned in Comment #2, and linking against > libstdc++.dll, I get this with your original testcaase: > > Expecting 'true', got 'true' > Expecting 'false', got 'false' > Where this patch is supposed to be applied to? trunk? I have looked through the patches you are referring to and through the source in repository. As far as I can see, libsupc++ is still static only, and eh_globals.cc is a part of libsupc++, not libstdc++. The fact that test-case works correctly for you could be just a coincidence. The more reliable way to check for the problem would be to compare the value returned by the __cxa_get_globals() when being from the main executable and from the dll respectively. I'll prepare the new test case.
Created attachment 18296 [details] Yet another test case This test checks whether main executable and dll share common abi::__cxa_eh_globals structure.
(In reply to comment #6) > (In reply to comment #5) > > > Applying Dave Korn's patch mentioned in Comment #2, and linking against > > libstdc++.dll, I get this with your original testcaase: > > > > Expecting 'true', got 'true' > > Expecting 'false', got 'false' > > > Where this patch is supposed to be applied to? trunk? Yes, it against trunk. > I have looked through the patches you are referring to and through the source > in repository. As far as I can see, libsupc++ is still static only, and > eh_globals.cc is a part of libsupc++, not libstdc++. libsupc++ is a convenience lib that is included in libstdc++ The fact that test-case > works correctly for you could be just a coincidence. The more reliable way to > check for the problem would be to compare the value returned by the > __cxa_get_globals() when being from the main executable and from the dll > respectively. I'll prepare the new test case. The new test case succeeds when I link against a shared libstdc++. Danny
Well, I have finally managed to build the trunk on Windows (mingw32). Now all test cases work fine for me without any patches (as of revision 156168 at least). Thanks.
Well, as user problem is solved and new gcc-version providing by default shared version for libstdc++/libgcc, I close this issue.