Description
Description
C++/CLI code. If I throw an unmanaged exception from the catch
block that handles a managed exception, an uncatchable SEHException is thrown and triggers the UnhandledException event handler of AppDomain. It is impossible (AFAIK) to detect whether this exception will terminate the application, because UnhandledExceptionEventArgs::IsTerminating is always true.
This is probably due to the new exception handling introduced in .NET 9, but setting DOTNET_LegacyExceptionHandling does not change this behavior.
Reproduction Steps
#pragma once
using namespace System;
#include "pch.h"
#include <stdexcept>
#include <iostream>
using namespace System;
#pragma managed
void Handler(Object^ sender, UnhandledExceptionEventArgs^ e) {
if (e->IsTerminating) {
Console::WriteLine("Terminating");
}
Console::WriteLine("Printing exception object:");
Console::WriteLine(e->ExceptionObject);
}
#pragma managed
void ManagedCodeCatchesManagedAndThrowsUnmanaged() {
AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(&Handler);
try {
Console::WriteLine(Environment::Version);
throw gcnew System::Exception("managed exception!");
}
catch (System::Exception^ e) {
Console::WriteLine("Caught managed exception");
Console::WriteLine(e->Message);
throw std::runtime_error("unmanaged error!");
}
}
#pragma unmanaged
extern "C" __declspec(dllexport) int main()
{
try {
ManagedCodeCatchesManagedAndThrowsUnmanaged();
}
catch (const std::runtime_error& e) {
std::cout << "caught unmanaged exception:" << std::endl;
std::cout << e.what() << std::endl;
}
return 0;
}
I couldn't manage to run this directly from Visual Studio, but I did create a C++ application that dynamically loads this library and invokes its main method. Here's the output with .NET 8:
8.0.15
Caught managed exception
managed exception!
caught unmanaged exception:
unmanaged error!
Here's the output from the .NET 10 preview (but it also happens with .NET 9):
10.0.0
Caught managed exception
managed exception!
Terminating
Printing exception object:
System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
at UnmanagedCodeThrows()
at ManagedCodeCatchesManagedAndThrowsUnmanaged() in C:\Users\samcook\source\repos\CppCliLib\CppCliLib\CppCliLib.h:line 35
Unhandled exception. System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
at UnmanagedCodeThrows()
at ManagedCodeCatchesManagedAndThrowsUnmanaged() in C:\Users\samcook\source\repos\CppCliLib\CppCliLib\CppCliLib.h:line 35
caught unmanaged exception:
unmanaged error!
Expected behavior
No SEHException should be thrown.
Actual behavior
An uncatchable SEHException is thrown and triggers the UnhandledException event handler.
Regression?
Yes. This workflow is fine in .NET Framework and up to/including .NET 8.
Known Workarounds
There are no workarounds. This prevents all MATLAB users from using .NET 9 and higher versions.
Configuration
No response
Other information
No response