An exception from the native failure flow of a .NET application without exception

I discovered a scenario when my .Net application unexpectedly crashes without any exception. I would like at least an AppDomain.UnhandledException work in this case, to allow me to at least register an error and present some information to the user.

In this scenario, I have a .Net assembly (let it be called A ) by calling interop on the native DLL (which we will call B ). B creates a flow and throws; If no one had caught the exception, I would have expected it to go all the way to the stack, back to my managed application, and finally become an unhandled exception.

At this point, I expected the OS to transfer control back to .Net, which would AppDomain.UnhandledException , and with that my application would end. However, the call is never completed.

Below I have included enough information to reproduce the problem. It can be ignored.

Program.cs

 internal class Program { public static void Main() { AppDomain.CurrentDomain.UnhandledException += _currentDomainUnhandledException; try { BugDllInterop.ErrorMethod(0); } catch (Exception e) { Console.WriteLine("Exception: " + e.GetType().Name); } Console.WriteLine("Clean exit."); } private static void _currentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine("Exception trapped."); } } 

BugDllInterop.cs

 public static class BugDllInterop { private const string BUG_DLL = "InteropExceptions.BugDll.dll"; [DllImport(BUG_DLL, CallingConvention = CallingConvention.Cdecl)] public extern static void ErrorMethod(int i); } 

Bugdll.h

 // INCLUSION GUARD #pragma once #define DllExport __declspec(dllexport) extern "C" { DllExport void ErrorMethod(int i); } 

Bugdll.cpp

 // HEADER ///////////////////////////////////////////////////////////////////// #include "BugDll.h" // LIBRARIES ////////////////////////////////////////////////////////////////// #include <windows.h> #include <fstream> #include <iostream> #include <time.h> using namespace std; // FUNCTIONS ////////////////////////////////////////////////////////////////// DWORD WINAPI threadMethod(LPVOID lpParameter) { throw 0; return 0; } void ErrorMethod(int i) { DWORD myThreadID; HANDLE myHandle = CreateThread(0, 0, threadMethod, 0, 0, &myThreadID); WaitForSingleObject(myHandle, 3000); CloseHandle(myHandle); } 

Again, I want the AppDomain.UnhandledException event to be raised. Of course, if someone knows how to properly handle the exception in order to support the application, that would be even better.

+4
source share
1 answer

You cannot catch and manage an exception created from another unmanaged thread.

When a method throws an exception, the CLR will only look for the handler in the thread in which the exception was thrown . This is even understandable, because the call stack of a thread begins with the thread itself.

You have a root exception handler because the CLR puts the handler at the top level (that will call your filter), but this is not true for unmanaged threads , so their exception can't be redirected .

The only solution for this situation is to throw an exception in the thread in which they are created. If your thread function can throw an exception, add catch there. In any case, not on the managed side. Managed / unmanaged borders are pretty thick here.

You might like to read this wonderful article on exception handling: http://www.microsoft.com/msj/0197/exception/exception.aspx

+2
source

Source: https://habr.com/ru/post/914373/


All Articles