我试图"测量"堆栈深度.为什么以下程序不打印任何内容?
class Program
{
private static int Depth = 0;
static void A(object o)
{
Depth++;
A(o);
}
static void B(object o, bool e)
{
Console.WriteLine(Depth);
}
static void Main(string[] args)
{
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(A, B, null);
}
}
Run Code Online (Sandbox Code Playgroud)
一些答案只包含来自MSDN的引用,如"从.NET Framework 2.0版开始,一个tryO catch块无法捕获StackOverflowException对象,默认情况下会终止相应的进程." 相信我,有时(当有足够的堆栈空间时)它可以是cought,下面打印一些数字就好了:
class Program
{
private static int depth = 0;
static void A(object o)
{
depth++;
if (Environment.StackTrace.Length > 8000)
throw new StackOverflowException("Catch me if you can.");
A(o);
}
static void B(object o, bool e)
{
Console.WriteLine(depth);
}
static void Main(string[] args)
{
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(A, B, null);
}
}
Run Code Online (Sandbox Code Playgroud)
关于你的编辑,我不认为抛出StackOverflowException的用户代码与抛出它的CLR相同.
还有一点关于它的讨论在这里.
Jeffrey(Richter,AppliedMicrosoft®.NETFramework Programming的作者)注释适用于实际堆栈溢出,即如果您的代码包含无限递归而发生的堆栈溢出,如:
void MyMethod(){MyMethod(); }
如果您自己抛出StackOverflowException,它将像任何其他异常一样处理,并且Jeffrey的注释不适用.
此外,杰弗里的评论说:"如果堆栈溢出发生在CLR本身......".因此,如果.NET VM可以"干净地"检测到堆栈溢出,即没有将ITSELF运行到堆栈溢出中,那么您应该得到一个StackOverflowException,并且您的catch和finally块应该像往常一样执行.但是,在VM ITSELF遇到堆栈溢出的悲惨情况下,您将不会那么幸运:VM不会传播StackOverflowException(但以其他一些奇怪的方式崩溃)并且您的catch和finally块将不会执行.
士气是:小心无限递归,因为你没有100%保证VM会检测并干净地发出信号!
布鲁诺.
澄清了自从OP引用该书以来"杰弗里"是谁.
如果你想捕获它,将它加载到另一个进程(通过远程处理回调你的进程)并让恶意代码在那里执行.另一个过程可能会终止,你可以得到一个整洁的SOE突然出现在你身边的管道末端 - 没有相当不方便的例外的不利影响.
请注意,同一进程中的单独AppDomain不会删除它.
如果您想从异常中获取堆栈跟踪,以下代码将为您提供良好的正义:
class Program
{
static void Main(string[] args)
{
try
{
Recurse(0);
}
catch (Exception ex)
{
StackTrace st = new StackTrace(ex);
// Go wild.
Console.WriteLine(st.FrameCount);
}
Console.ReadLine();
}
static void Recurse(int counter)
{
if (counter >= 100)
throw new Exception();
Recurse(++counter);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |