我有一个相当简单的程序,作为库存跟踪程序运行。它是一个单线程,.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;
}
}
然而,没有任何消息出现过。还有什么办法可以追踪这个?
答案 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(如果适用),这样你就可以验证这里是否有异常?