Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-2055

Set /EHsc when building on Visual Studio

    • Type: Icon: Task Task
    • Resolution: Gone away
    • Priority: Icon: Major - P3 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?

            Assignee:
            Unassigned Unassigned
            Reporter:
            kevin.albertson@mongodb.com Kevin Albertson
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: