[CXX-2055] Set /EHsc when building on Visual Studio Created: 18/Jun/20  Updated: 27/Oct/23  Resolved: 12/Jan/23

Status: Closed
Project: C++ Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Kevin Albertson Assignee: Unassigned
Resolution: Gone away Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CXX-2054 Run full test suite on Windows 2017+ Closed
related to CXX-2629 Remove requirement to set `/Zc:__cplu... Closed

 Description   

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?


 Comments   
Comment by Kevin Albertson [ 12/Jan/23 ]

Configuring the C++ driver version 3.7.0 and older with C++17 in Visual Studio must also include the /EHsc flag:

'C:\Program Files (x86)\CMake\bin\cmake.exe' .. \
    -G "Visual Studio 15 2017 Win64"            \
    -DCMAKE_CXX_STANDARD=17                     \
    -DCMAKE_CXX_FLAGS="/Zc:__cplusplus /EHsc"   \
    -DCMAKE_PREFIX_PATH=C:\mongo-c-driver       \
    -DCMAKE_INSTALL_PREFIX=C:\mongo-cxx-driver  \

The installation documentation incorrectly did not include /EHsc.

/EHsc is the documented default for the exception handling model. Omitting the /EHsc may result in incorrect stack unwinding behavior. Omitting the /EHsc flag results in an Internal Compiler error when building tests on Visual Studio 2022.

In 3.7.1 and newer, this is resolved by CXX-2629. The fix of CXX-2629 longer requires CMAKE_CXX_FLAGS to be specified.

Comment by Kevin Albertson [ 18/Jun/20 ]

Note, the server sets this as well: https://github.com/mongodb/mongo/blob/v4.2/SConstruct/#L1644-L1646

Generated at Wed Feb 07 22:04:45 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.