无法追踪的错误

时间:2014-09-11 13:58:58

标签: c# winforms

我有一个相当简单的程序,作为库存跟踪程序运行。它是一个单线程,.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;
        }
    }

然而,没有任何消息出现过。还有什么办法可以追踪这个?

2 个答案:

答案 0 :(得分:2)

如果不触发您编写的事件处理程序,.NET程序可能会崩溃到桌面有三个基本原因。我认为它不像你的代码中的Environment.Exit()那样显而易见:

  • StackOverflowException。没有足够的堆栈空间可以安全地执行任何操作,包括触发这些事件。如果你有一个调试器,你总会知道它,但是当你运行没有一个调试器时根本没有通知。

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

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

这三个中的哪一个会使你的程序崩溃是你必须要找到困难的方法。发现接下来需要寻找哪种方式的最基本方法是关注进程退出代码。它的值将为非零以指示失败,它将设置为匹配的基础SEH异常代码。当您在重现崩溃时遇到问题时,您可能需要编写一个小帮助程序,除了使用Process类启动主程序之外什么都不做。当它停止时,Process.ExitCode会为您提供值。

毋庸置疑,这可能需要一段时间才能得到解决,因此请分配您需要的资源来磨练问题。需要进行广泛的测试以获得repro。保持你的手指交叉一个简单的SOE,到目前为止最常见的原因,其他两个非常丑陋,你可能需要微软支持。

答案 1 :(得分:1)

Windows x64中有known issue about swallowed Exceptions in the Load() event

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