You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6及更高版本中如何捕获或记录SEH异常?

.NET 6+ 中获取SEH异常堆栈追踪的方法

在.NET 6及更高版本中,HandleProcessCorruptedStateExceptionsAttribute确实已失效,要获取SEH异常的堆栈追踪,可通过以下几种实用方式解决:

1. 启用旧版异常处理开关

通过AppContext设置开关,恢复.NET 4.8时期允许捕获SEH异常的行为,这样就能在try-catch中获取堆栈信息:

// 应用启动时(比如Program.cs开头)设置开关
AppContext.SetSwitch("Switch.System.Runtime.HandleProcessCorruptedStateExceptions", true);

// 在可能触发SEH异常的代码块中捕获
try
{
    // 执行可能抛出SEH异常的操作(比如调用非托管代码)
}
catch (Exception ex)
{
    // 直接获取并记录堆栈追踪
    string stackTrace = ex.StackTrace;
    // 输出到日志或控制台
    Console.WriteLine($"SEH异常堆栈:\n{stackTrace}");
}

注意:这类异常通常意味着进程状态已损坏,捕获后建议记录信息后立即终止应用,避免后续出现不可预期的问题。

2. 生成崩溃转储文件

如果SEH异常直接导致应用崩溃,可通过生成崩溃转储文件,事后用调试工具分析完整堆栈:

代码方式生成转储

在全局异常事件中调用Windows API生成小型转储:

using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

class Program
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
        // 执行业务代码
    }

    private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.IsTerminating)
        {
            using var process = Process.GetCurrentProcess();
            using var dumpFile = File.Create($"crash_{process.Id}.dmp");
            MiniDumpWriteDump(
                process.Handle,
                (uint)process.Id,
                dumpFile.SafeFileHandle.DangerousGetHandle(),
                MiniDumpType.MiniDumpNormal,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero);
        }
    }

    [DllImport("DbgHelp.dll")]
    private static extern bool MiniDumpWriteDump(
        IntPtr hProcess,
        uint processId,
        IntPtr hFile,
        MiniDumpType dumpType,
        IntPtr exceptionParam,
        IntPtr userStreamParam,
        IntPtr callbackParam);

    private enum MiniDumpType
    {
        MiniDumpNormal = 0x00000001
    }
}

系统级自动生成转储

通过Windows系统设置,让应用崩溃时自动生成转储:

  • 打开「任务管理器」→「详细信息」,右键目标进程→「创建转储文件」
  • 或通过注册表配置全局崩溃转储策略,具体可搜索Windows系统崩溃转储设置,生成的转储文件可使用Visual Studio或WinDbg打开分析完整堆栈。

3. 全局异常日志记录

注册全局异常事件,尽可能捕获崩溃前的上下文信息,辅助排查:

AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
    if (e.ExceptionObject is Exception ex)
    {
        // 记录异常消息、堆栈(如果能获取)、当前线程信息等
        Console.WriteLine($"崩溃异常: {ex.Message}\n堆栈: {ex.StackTrace}");
    }
};

内容的提问来源于stack exchange,提问作者Coragi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:08:17