Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLR exceptions in mixed-mode modules #1138

Closed
davidaue opened this issue Dec 22, 2017 · 5 comments
Closed

CLR exceptions in mixed-mode modules #1138

davidaue opened this issue Dec 22, 2017 · 5 comments

Comments

@davidaue
Copy link
Contributor

davidaue commented Dec 22, 2017

Description

In a mixed-mode (native c++ & c++/cli) module native code calls back to the CLR and a CLR exception is thrown. With the right combination of switches this will be caught by catch(...). In this circumstance std::current_exception returns nullptr. The translators rethrow the nullptr causing a bad_exception. My fix is shown below. I believe this applies to all Windows structured exceptions but I'm a bit rusty on the details.

 std::string ExceptionTranslatorRegistry::translateActiveException() const {
    try {
#ifdef __OBJC__
        // In Objective-C try objective-c exceptions first
        @try {
            return tryTranslators();
        }
        @catch (NSException *exception) {
            return Catch::Detail::stringify( [exception description] );
        }
#else
        // Windows SEH exceptions caught in native code will have no current_exception
        if (std::current_exception() == nullptr)
            return "Non C++ exception";

        return tryTranslators();
#endif
    }
  • Catch version: 2.0.1
  • Operating System: Windows 10
  • Compiler+version: MSVC 15.5.2
@horenmar
Copy link
Member

That is an interesting use-case.

Can you provide the set of switches to reproduce this? I want to see what happens inside our SE handlers first.

@davidaue
Copy link
Contributor Author

davidaue commented Jan 13, 2018

Causing any structured exception should be exactly the same and is easier to reproduce than my specific case which involves mixed-mode. This works with the just /EHa switch which allows SEH exceptions to be caught with try/catch.

try {
    auto i = *((int*)nullptr); // cause exception
}
catch (...) {
    auto ex = std::current_exception();  // ex will be nullptr
}

Catch2 is doing the catch(...) and then uses the nullptr returned from current_exception() in the filtering code, causing a second exception (if I remember correctly).

@horenmar
Copy link
Member

I got around experimenting with this and, at least for SEH, std::current_exception() == nullptr will evaluate to false when SEH exception was caught inside catch (...) block. Even the rethrow mostly works*, but the Console reporter goes crazy afterwards.

@davidaue
Copy link
Contributor Author

You are right. I was fooled by how the debugger displays std::exception_ptr. It's good we found another case though! I attached an example project to show CLR exceptions caught in native code, which really do evaluate == nullptr.

CatchSEH.zip

@horenmar
Copy link
Member

I was fooled by how the debugger displays std::exception_ptr.

Yep, spent some time there as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants