例外的本地线程崩溃无一例外.NET应用程序线程、应用程序、NET

2023-09-03 17:48:57 作者:回不去旳情

我已经发现了这样一个场景,我的.NET应用程序会意外崩溃而不引发任何异常。我想,至少, AppDomain.UnhandledException 曾在这种情况下,为了使我至少有一些信息记录错误和present用户

I have discovered a scenario where my .Net application will crash unexpectedly without raising any exceptions. I would like that, at least, AppDomain.UnhandledException worked in this case, in order to enable me at least to log the error and present the user with some information.

在这种情况下,我有一个.NET程序集(姑且称之为 A )与互操作调用本机DLL(我们称之为 B )。 B创建一个线程,并抛出;没有任何人来捕获异常,我希望它一路走下去堆栈,回到我的托管应用程序,然后最终成为一个未处理的异常。

In this scenario, I have an .Net assembly (let's call it A) with an interop call to a native DLL (which we will call B). B creates a thread and throws; Without anyone to catch the exception, I'd expect it to go all the way up the stack, back into my managed application, and then finally become an unhandled exception.

在这一点上我希望操作系统到手的控制权交还给净,这会叫 AppDomain.UnhandledException ,并与该,我的应用程序将结束。然而,该呼叫不会被制成。

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

下面我包含足够的信息来重现问题。它可以忽略不计。

的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);

}

此外,我需要的就是这样的 AppDomain.UnhandledException 事件引发。当然,如果有人知道如何正确的,以保持应用程序正常处理的异常,这将是更好的。

Again, my desired is just that the AppDomain.UnhandledException event is raised. Of course, if anyone knows how to properly handle the exception in order to keep the application alive, it would be even better.

推荐答案

您不能捕获和管理异常从其他非托管线程中抛出。

You can't catch and manage exception thrown from another unmanaged thread.

当一个方法抛出一个异常,CLR将搜索处理程序的仅在异常已引发线程。这是因为一个线程调用栈开始线程本身甚至可以理解的。

When a method throws an exception the CLR will search for a handler only in the thread where the exception has been thrown. It's even understandable because the call stack of a thread begins with the thread itself.

您有一个的根的异常处理程序,因为CLR将一个处理器在顶层(一会调用过滤器),但这是不正确的非托管线程所以的异常不能被转发

You have a root exception handler because the CLR puts a handler at the top level (the one will invoke your filter) but this isn't true for unmanaged threads so their exception can't be forwarded.

对于这种情况,唯一的解决办法是在他们的线程的赶上例外。如果你的线程函数可以抛出一个异常,然后添加一个catch那里。反正不是在托管方。托管/非托管边界是pretty的厚这里。

The only solution for this situation is to catch exception in the thread where they are originated. If your thread function can throw an exception then add a catch there. Anyway not on the managed side. Managed/unmanaged boundaries are pretty thick here.

您可能想了解这个有关的异​​常处理好文章:的http:// www.microsoft.com/msj/0197/exception/exception.aspx

You may like to read this nice article about exception handling: http://www.microsoft.com/msj/0197/exception/exception.aspx