-
Type: Task
-
Resolution: Gone away
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
When running tests on Visual Studio 2017 in CXX-2042, test failures were observed that indicated destructors were not being called in tests that expected an exception to be thrown.
The compiler output when building the test_driver target produced the multiple warnings like this one:
C:\code\mongo-cxx-driver\src\mongocxx\test\model\insert_one.cpp(33,9): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc [C:\code\mongo-cxx-driver\cmake-build\src\mongocxx\test\test_driver.vc xproj]
Sure enough, setting /EHcs for building tests resolved the issue.
However, it is not clear to me why this is not the default behavior for C++ exception handling, and whether we need to make a change in our documentation or cmake scripts to account for this.
This page indicates that /EHcs should be the default.
https://docs.microsoft.com/en-us/cpp/cpp/exception-handling-in-visual-cpp?view=vs-2017
Use an /EH compiler option to specify the exception handling model to use in a C++ project. Standard C++ exception handling (/EHsc) is the default in new C++ projects in Visual Studio.
Though this page indicates that the default behavior may only partially support standard C++ exception handling:
https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=vs-2017#default-exception-handling-behavior
The compiler always generates code that supports asynchronous structured exception handling (SEH). By default (that is, if no /EHsc, /EHs, or /EHa option is specified), the compiler supports SEH handlers in the native C++ catch(...) clause. However, it also generates code that only partially supports C++ exceptions. The default exception unwinding code doesn't destroy automatic C++ objects outside of try blocks that go out of scope because of an exception. Resource leaks and undefined behavior may result when a C++ exception is thrown.
Additionally, this StackOverflow answer indicates that crossing the extern C boundary requires setting /EHs. This may be relevant to the implementation of the with_transaction helper, which calls a C++ supplied callback through a libmongoc function. https://github.com/mongodb/mongo-cxx-driver/blob/master/src/mongocxx/client_session.hpp#L144-L166
- Is /EHcs only necessary for our tests?
- Should we always specify /EHcs when compiling with MSVC?
- If not, should we document this for users?