是否可以删除或插入C#调用堆栈中的帧?

时间:2011-09-04 13:27:54

标签: c# callstack

使用StackTrace我可以获得堆栈帧。我的问题是,是否可以在C#中操纵调用堆栈?更具体地说:是否可能......

  • 将帧插入调用堆栈?或

  • 从中删除一个框架?

5 个答案:

答案 0 :(得分:4)

Stack是程序运行时的一个非常内部的组件。有能力改变它可以:

  • 制作几乎不受限制的goto。某些东西被认为是一种非常糟糕的编程习惯,即使在PHP中也是不可能的。调试这样的东西会很乱。
  • 在方法返回时注入代码。这可能很有用,但已经被面向方面的工具所覆盖,例如 PostSharp Spring.NET ,它们允许您以干净和可预测的方式执行此操作。而且它们涵盖的范围远远超过方法返回。

因此,我认为没有任何编程语言允许您显式操作堆栈。它会使事情变得非常混乱,并且它可能产生的任何好处已经被面向方面编程所涵盖。我打赌 AOP 会让你达到你想要的效果。

答案 1 :(得分:1)

StackTrace类不支持这种操作。根据msdn只读取帧(只有GetFrame,GetFrames方法可用)。

要了解如何通过框架创建类,您可以直接查看类的源代码。

答案 2 :(得分:1)

不,这是不可能的。 The Stack Is An Implementation Detail。 此外,操纵堆栈的能力将带来很多安全/一致性问题。这就是为什么操纵堆栈是一个不好的做法/安全错误,即使你可以这样做(例如在C中)。例如,臭名昭着的“缓冲区溢出”类别的安全性问题正是由此产生的:能够在代码中插入“goto”,一个新的堆栈帧,以便在返回时执行恶意有效负载而不是合法调用功能

但是,那你为什么要这样做呢?鉴于一个真正的目标,我们可以更好地推理如何做到这一点,并建议好的替代方案

答案 3 :(得分:1)

在Smalltalk中操作堆栈很容易,但我认为在C#中它是不可能的。

答案 4 :(得分:0)

是的,你可以通过反思。 最终它是一个字符串。

以下是使用javascript stacktrace作为C#异常Javascript来记录preserving the original stack trace异常的异常类。

using System.Reflection;
    public class JsException : Exception
    {
        static readonly FieldInfo _stackTraceString = typeof(Exception).GetField("_stackTraceString", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
        public JsException(string error, string stack)
            : base(error)
        {
            _stackTraceString.SetValue(this, stack);
        }
    }