我知道这很模糊,但这是我能收集到的。我希望有人能够了解这可能会如何发生。
我有一个64位程序,我在Win 7 64位机器上运行,内置于Visual Studio 2012.
它使用位于另一个项目中的类(编译为dll)。该类有一个错误的迭代器,可能导致堆栈溢出。调用该buggy迭代器的操作是通过任务调用的。
所以在我的程序中,代码如下所示:
new Task(()=>{
try
{
DoWork(); //<-- buggy iterator is called inside
}
catch (Exception ex)
{
//Exception reported to user
}
}).Start();
代码每次都在相同的数据上执行,并且没有随机变量或guid生成,所以每次都应该产生相同的输出。
大多数情况下,它会在
现在,它有时会捕获异常(显示导致异常的代码中的正确位置)。这是随机的,但如果我更频繁地破坏任务(例如在工作期间随机插入断点),似乎会发生更多。
但是,我还是无法继续申请。尽管异常发生在一个try-catch块中,它应该捕获StackOverflowException(它应该捕获它,因为StackOverflowException包含在Exception中 - C#不会让你同时捕获它们并明确告诉你SOE已经包含在E中)。
我尝试制作一个小程序,在try-catch块内部故意堆栈溢出,并且它还显示“程序必须关闭,让我在线检查解决方案”系统窗口而不是正确处理。这是代码:
private bool Overflow()
{
return Overflow();
}
private void button1_Click(object sender, EventArgs e)
{
try { Overflow();}
catch (StackOverflowException ex) { }
}
因此,我有几个问题:
问题1:
是否有可能捕获StackOverflowExceptions?我该怎么做?
问题2:
当你的dll(同一解决方案中的其他项目)内发生堆栈溢出时,什么可以使VS 2012调试器认为它是“未知模块”?
问题3:
为什么要与部落乐器进行一些奇妙的魔术舞蹈,这样可以减少这种情况? (我的意思是随机打破正在进行的程序)
总的来说,发生了什么?
提前致谢
答案 0 :(得分:1)
您不能捕获真正的堆栈溢出异常,这就是为什么它不起作用。
另见this讨论。
我不能回答你的第二个问题,除了说“程序真的搞砸了”。
对于你的第三个问题:因为它在一个单独的线程中运行,它运行的代码量将根据你打破程序的时间而有所不同。我认为你能够解决这个问题的唯一方法是通过一些繁琐的逐行调试,或者大量的Debug.WriteLine()。
答案 1 :(得分:0)
1)从.NET Framework 2.0版开始,try-catch块无法捕获StackOverflowException对象,默认情况下会终止相应的进程。因此,建议用户编写代码以检测并防止堆栈溢出。例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环。请注意,承载公共语言运行时(CLR)的应用程序可以指定CLR卸载发生堆栈溢出异常的应用程序域,并让相应的进程继续。有关更多信息,请参阅ICLRPolicyManager接口和主机概述。 (http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx)