【问题标题】:What happens at OS level when a .net program exits due to an uncaught exception?当 .net 程序由于未捕获的异常而退出时,操作系统级别会发生什么?
【发布时间】:2011-02-26 07:46:39
【问题描述】:

实际问题:

当程序因未捕获的异常而崩溃时,“在 Windows 中”会发生什么?

是否有一个我可以挂钩的 dll 函数来记录有关崩溃的一些基本信息?

上下文:

我正计划编写一个程序,该程序将收集有关在我的本地 PC 上崩溃的任何应用程序的一些非常基本的信息。我希望我可以执行一个简单的方法来记录有关崩溃的一些信息,其方式类似于 Visual Studio 生成对话框的方式,让您在程序崩溃时对其进行调试。

【问题讨论】:

  • 您的问题似乎与 .net 无关,因为您本地 PC 上的许多应用程序不一定是 .net 应用程序。
  • 是的,你是对的。澄清一下,我对 .net 应用程序造成的崩溃最感兴趣,因为它们很可能是由我造成的。
  • AFAIK,.Net 未捕获的异常不是崩溃。当操作系统本身捕获 SEH 异常并调用 TerminateProcess 时,就会发生崩溃。 .Net 异常被 CLR 捕获,并导致调用 ExitProcess - 更好的退出。

标签: .net windows exception


【解决方案1】:

托管异常是使用常规 Windows 结构化异常处理机制实现的。异常代码为 0xe0434f4d。 Windows 会寻找愿意处理异常的异常处理程序。如果代码在堆栈上没有活动的 try 块,或者没有 catch 块愿意捕获托管异常,则托管代码中的最后一个喘息是 AppDomain.UnhandledException 事件。

如果在异常处理切换到非托管处理时没有实现,则使用 SetUnhandledExceptionFilter 设置的异常过滤器将获得成功。如果做不到这一点,Windows 总会提供一个默认处理程序。通常调用 WER,即 Windows 错误报告程序。这为用户提供了一个将异常详细信息发送给 Microsoft 的对话框。不要期待任何结果。

当它超出 AppDomain.UnhandledException 时,有关托管异常的所有信息都将丢失。没有堆栈跟踪,没有异常消息。只是您已经知道的异常代码和一个您将无用的异常地址,因为代码是由 JIT 编译器动态生成的。

确保在最后喘息阶段捕获异常,为 AppDomain.UnhandledException 编写事件处理程序。记录 e.ExcdeptionObject.ToString() 的值并使用 Environment.Exit() 终止程序。还要注意 Windows 窗体代码中的 Application.ThreadException 事件和 WPF 代码中的 Dispatcher.UnhandledException 事件。它们是在 UI 线程上处理事件时引发的异常的后盾。

【讨论】:

    【解决方案2】:

    对于原生应用,您可以使用以下函数:

    此外,您还可以使用AddVectoredExceptionHandler,尽管我不建议这样做,因为它还会拦截捕获的异常。

    您传递给 SetUnhandledExceptionFilter 的函数指针获取一个结构作为输入参数,其中包含有关异常的所有信息(原因、寄存器、...)。

    在我的应用程序中,如果应用程序崩溃,我会使用 SetUnhandledExceptionFilter 创建应用程序转储(使用 DBGHELP.DLL dll 中的函数 MiniDumpWriteDump)。 小心不要在那个函数中做太多。由于您的应用程序已经崩溃,因此不能保证任何进一步的逻辑仍然有效(例如,访问您自己的可能正确的数据结构可能会导致进一步的崩溃)。

    考虑购买 John Robbins 的《Debugging Microsoft NET 2.0 Applications》一书。我从这本书中学到了很多东西,包括这个技巧。

    【讨论】:

    • 这假设您有代码在进程中运行,如果您想监控所有进程,这通常是一个坏主意。
    • @MSalters,是的,但实际上它是一个很容易添加到可执行文件的功能,并且不需要您的客户安装额外的可执行文件(或运行单独的监控进程)
    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2013-03-23
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多