4

我知道这很模糊,但这是我能收集到的全部信息。我希望有人对这可能发生的情况有所了解。

我有一个 64 位程序,我在 Win 7 64 位机器上运行,内置于 Visual Studio 2012。

它使用位于另一个项目中的类(编译为 dll)。该类有一个错误的迭代器,可能导致堆栈溢出。调用错误迭代器的操作是通过任务调用的。

所以在我的程序中,代码如下所示:

new Task(()=>{
try
{
    DoWork(); //<-- buggy iterator is called inside
}
catch (Exception ex)
{
    //Exception reported to user
}
}).Start();

该代码每次都在相同的数据上执行,并且不涉及随机变量或 guid 生成,因此每次都应该产生相同的输出。

大多数时候,它会在 Unknown Module 中发生 StackOverflowException崩溃(尽管我知道它到底发生在哪里)。如果发生这种情况,我无法查看发生溢出的代码点,并且 try-catch 块什么也不做!我无法继续执行该程序(如果我在没有调试的情况下运行它,它会显示“必须关闭程序让我们在线检查解决方案”系统窗口)。

现在,有时它会捕获异常(显示导致异常的代码中的正确位置)。这是随机的,但如果我更频繁地中断任务(比如在任务工作期间随机插入断点),似乎会发生更多。

但是,我仍然无法继续申请。即使异常发生在应该捕获 StackOverflowException 的 try-catch 块内(它应该捕获它,因为 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) { }
    }

因此,我有几个问题:

问题一:

是否有可能捕获 StackOverflowExceptions?我该怎么做?

问题2:

当您的 dll(同一解决方案中的其他项目)内部发生堆栈溢出时,什么可以让 VS 2012 调试器认为它是“未知模块”?

问题 3:

为什么用部落乐器做一些奇怪的魔术舞蹈会减少这样做的频率?(我的意思是随机破坏正在进行的程序)

总的来说,这是怎么回事?

提前致谢

4

2 回答 2

1

不允许您捕获真正的堆栈溢出异常,这就是它不起作用的原因。

另请参阅讨论。

我无法回答你的第二个问题,只能说“程序真的很乱”。

对于您的第三个问题:因为它在单独的线程中运行,所以它运行的代码量将根据您何时中断程序而有所不同。我认为您能够深入了解这一点的唯一方法是通过一些繁琐的逐行调试或大量 Debug.WriteLine()。

于 2013-04-09T08:38:26.450 回答
0

1) 从 .NET Framework 2.0 版本开始,StackOverflowException 对象无法被 try-catch 块捕获,相应的进程默认终止。因此,建议用户编写代码来检测和防止堆栈溢出。例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环。请注意,承载公共语言运行时(CLR)的应用程序可以指定CLR卸载发生堆栈溢出异常的应用程序域,并让相应的进程继续进行。有关详细信息,请参阅 ICLRPolicyManager 接口和托管概述。(http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx

于 2013-04-09T08:39:19.737 回答