TL; TR
当我问这个问题时,我假设a StackOverflowException是一种阻止应用程序无限运行的机制.这不是真的.
A StackOverflowException未被检测到.
当堆栈没有分配更多内存的容量时抛出它.
[原始问题:]
这是一个普遍的问题,每个编程语言可能有不同的答案.
我不确定C#以外的语言如何处理堆栈溢出.
我今天经历了例外,并一直在思考如何StackOverflowException检测到它.我相信不可能说fe是否深度为1000次调用,然后抛出异常.因为在某些情况下,正确的逻辑可能会那么深.
在我的程序中检测无限循环的逻辑是什么?
StackOverflowExceptionclass:
https://msdn.microsoft.com/de-de/library/system.stackoverflowexception%28v=vs.110%29.aspx类文档中
提到的交叉引用StackOverflowException:https:
//msdn.microsoft.com/de -de /库/ system.reflection.emit.opcodes.localloc(v = vs.110)的.aspx
我刚刚在stack-overflow这个问题上添加了标记,并且描述说当调用堆栈消耗太多内存时它会被抛出.这是否意味着调用堆栈是我的程序的当前执行位置的某种路径,如果它不能存储更多的路径信息,那么抛出异常?
假设您有一种方法可能会陷入无休止的方法调用循环并且崩溃并发生StackOverflowException.例如,我RecursiveSelect在这个问题中提到的天真方法.
从.NET Framework 2.0版开始,try-catch块无法捕获StackOverflowException对象,默认情况下会终止相应的进程.因此,建议用户编写代码以检测并防止堆栈溢出.例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环.
把这些信息(来自这个答案)考虑在内,因为无法捕获异常,是否可以为这样的事情编写测试?或者对此进行测试,如果失败,实际上会打破整个测试套件?
注意:我知道我可以尝试一下,看看会发生什么,但我对它的一般信息更感兴趣.比如,不同的测试框架和测试运行器会以不同的方式处理吗?即使有可能,我应该避免这样的测试吗?
我正在使用FirstChanceException事件来记录有关任何抛出异常的详细信息.
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
Console.WriteLine("Inside first chance exception.");
};
throw new Exception("Exception thrown in main.");
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作.但是如果在事件处理程序中抛出异常,则会发生堆栈溢出,因为事件将以递归方式引发.
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
throw new Exception("Stackoverflow");
};
throw new Exception("Exception thrown in main.");
}
Run Code Online (Sandbox Code Playgroud)
如何处理事件处理程序中发生的异常?
编辑:
有一些答案表明我将代码包装在try/catch块中的事件处理程序中,但这不起作用,因为在处理异常之前引发了事件.
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
try
{
throw new Exception("Stackoverflow");
}
catch
{
}
};
throw new Exception("Exception thrown in main.");
}
Run Code Online (Sandbox Code Playgroud) 在.NET中遇到一些StackOverflowExceptions之后,我注意到它们完全绕过了.NET提供的未处理的异常处理程序(Application.ThreadException/AppDomain.UnhandledException).这非常令人不安,因为我们在这些异常处理程序中有关键的清理代码.
有没有办法克服这个问题?
一个奇怪的问题:
如果当前进程的堆栈已满,如何显示着名的"Process因StackOverflowException而终止"屏幕?是运行时保存一些寄存器以使其正常降级,还是内部技巧可能会运行另一个显示此屏幕的临时进程?
PS了解这个问题的可能答案可以帮助某人建立自己的"优雅降级(假设显示此类消息的功能非常有限)"来自类似的关键故障情况的机制.

我有一个应用程序在设备模拟器上正常工作但在真实设备上它会在一段时间后崩溃.在1-2分钟后,也可能在几分钟后发生.这个问题既可以单独使用,也可以连接到visual studio.
关键是没有异常被抛出,VS只是报告连接丢失了.我确实检查过我是否使用了太多内存,但事实并非如此(http://stackoverflow.com/questions/4239193/whats-causing-my-wp7-app-to-crash).
什么可以导致应用程序崩溃而不抛出异常?
我正在编写一些可以加载第三方程序集的c#.
如果第三方决定是恶意的,他们可以编写一个递归函数,最终会出现在StackOverflowException中,从而导致我的应用程序崩溃.
是否可以检测递归函数?
更新: 对于像while(true)或(;;)这样的不良状态,我已经有了解决方案.本质上,我在一个单独的线程中运行第三方代码,如果线程花费的时间超过固定的持续时间,我就拔掉插件.这不适用于递归,因为达到堆栈限制非常快.
更新: 也许我错误地表达了我所追求的解决方案.如果我最终得到大量故意恶意代码,我将更改应用程序以在单独的进程中运行第三方代码.但是在这个阶段,我假设代码只会导致问题,因为它编写得很糟糕.
接受的答案 我已经决定最好的方法是在一个单独的过程中运行第三方库.我可以运行多个进程实例,甚至可以跨进程对我的第三方库进行一种负载平衡.如果执行杀死其中一个进程的恶意代码,我应该能够检测到哪个库将其杀死,将该库标记为恶意,并使用所有非恶意库重新启动该进程.
感谢大家的好建议!
背景:
我正在处理一个非常旧的应用程序,它很少并且非常间歇性地生成异常。
目前的做法:
通常我们程序员使用全局异常处理程序处理罕见的未知数,连接如下:
[STAThread]
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
private static void Main()
{
Application.ThreadException += new ThreadExceptionEventHandler(UIThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new OldAppWithLotsOfWierdExceptionsThatUsersAlwaysIgnore());
}
private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
{
//-------------------------------
ReportToDevelopers("All the steps & variables you need to repro the problem are: " +
ShowMeStepsToReproduceAndDiagnoseProblem(t));
//-------------------------------
MessageToUser.Show("It’s not you, it’s us. This is our fault.\r\n Detailed information about this error has automatically been recorded and we have been notified.Yes, we do look at …Run Code Online (Sandbox Code Playgroud) 我不知道为什么我无法处理由该代码引起的此异常:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
int id = int.Parse(((DataRowView)checkedListBox1.Items[i])[0].ToString());
bool check = checkedListBox1.GetItemChecked(i);
DataRow[] dr = dt.Select("id = " + id.ToString());
dr[0][2] = check;
}
}
catch (StackOverflowException) { }
}
Run Code Online (Sandbox Code Playgroud)