无法跟踪的错误

本文关键字:错误 跟踪 | 更新日期: 2023-09-27 18:21:35

我有一个相当简单的程序,可以作为库存跟踪程序运行。它是一个单独的线程,.net 4.0,并且完全由事件驱动(如果不点击按钮,什么都不会发生)。程序在没有单击按钮的情况下崩溃。以下是我尝试获取有关此错误的任何信息所采取的措施:

第一:查找未编索引的异常或线程异常。为这个错误创建一个弹出的消息框和一个数据库条目:

static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.Run(new archiveInventory_b());
    }
    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception");
        ErrorLogEntry(e.Exception.Message + " INNER EXCEPTION: " + e.Exception.InnerException.Message, "ThreadException");
    }
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
        ErrorLogEntry((e.ExceptionObject as Exception).Message + " INNER EXCEPTION: " + (e.ExceptionObject as Exception).InnerException.Message, "UnhandledException");
    }

程序关闭,没有消息框或数据库条目。

第二:在程序关闭时抓住罪魁祸首:

private static void form_Closing(object sender, CancelEventArgs e)
    {
        const string message =
    "Are you sure that you would like to close the program?";
        const string caption = "Form Closing";
        var result = MessageBox.Show(message, caption,
                                     MessageBoxButtons.YesNo,
                                     MessageBoxIcon.Question);
        // If the no button was pressed ... 
        if (result == DialogResult.No)
        {
            // cancel the closure of the form.
            e.Cancel = true;
        }
    }

然而,从未出现过任何信息。还可以做些什么来追踪这件事?

无法跟踪的错误

.NET程序可以在不启动您编写的事件处理程序的情况下崩溃到桌面的原因有三个。我假设它不是像代码中的Environment.Exit()那样明显的东西:

  • StackOverflow异常。没有足够的堆栈空间来安全地执行任何操作,包括启动这些事件。当你有一个调试器时,你就会知道它,但当你在没有调试器的情况下运行程序时,你根本不会收到通知。

  • ExecutionEngineException。CLR在检测到其内部数据结构已损坏时引发。到目前为止,最常见的原因是GC堆的损坏,这反过来又是由错误的pinvoke声明或行为不端的非托管代码引起的。诊断极其困难,损坏总是在碰撞发生之前很久就发生了。

  • A/GS违规/GS是C++编译器选项的名称,它向代码添加额外的检查,以验证处理器堆栈是否已损坏。一种非常常见的恶意软件攻击向量,一种让处理器只使用数据执行任意代码的方法/CLR中存在GS检查以及抖动生成的代码。这样的事故非常罕见,最初的.NET 4.0版本在CLR中有一些错误,错误地触发了这次检查,但我已经很久没有听说过了。它们可以通过调试器进行诊断,但是必须启用非托管代码调试。

这三者中的哪一个破坏了你的程序,这是你必须通过艰难的方式找到的。发现下一步需要走哪条路的最基本方法是关注流程出口代码。它的值将为非零,表示失败,它被设置为匹配的基础SEH异常代码。当您在再现崩溃时遇到问题时,您可能需要编写一个小的辅助程序,该程序除了使用Process类来启动主程序之外什么都不做。当它停止时,Process.ExitCode会为您提供值。

也许不用说,这需要一段时间才能解决,所以分配你需要的资源来解决这个问题。需要进行广泛的测试以获得重新编程。请为一个简单的SOE祈祷,这是迄今为止最常见的原因,另外两个非常丑陋,你很可能需要微软的支持。

在Windows x64中的Load()事件中存在一个已知的关于吞下异常的问题。

为了消除这个原因(或检查它…),你能在你的加载事件中添加一个try/catch吗(如果适用),这样你就可以验证这里是否发生了任何异常?