我可以更改C#中的当前堆栈跟踪吗?
总之,我需要修改C#中的当前堆栈跟踪,以便我调用的方法(我无法修改)会认为它是其他人调用它的方法。
现在,为了说明为什么我需要做这样一个可怕的黑客行为。
在Unity3d中,Debug.Log在开发人员控制台中创建一条新记录。 当你双击它时,它会打开IDE显示对该记录负责的确切文件和行。 但是,由于各种原因(禁用生产中的调试,使其可用于其他线程)我创建了一个包装类Print
,而不是UnityEngine.Debug。
但是对于包装器,现在当开发人员在控制台中单击日志记录时,打开的是Print
,而不是调用Print.Log
的实际位置。 而且由于Debug.Log
不管错误消息或上下文对象如何执行,我都认为它使用调用堆栈来标识要打开的文件。 不用说,我想解决这个问题。
我不相信这是可能的。 查看Environment.StackTrace
的源代码和后续的GetStackTrace()
调用,我们可以看到它每次调用时都会创建堆栈跟踪。 由于似乎没有什么可以注入来改变它的某些工作,所以我认为可以断定,如果不修改它的调用方式,就不能更改堆栈跟踪。
如果你有可能做到这一点,你可以使用类似这样的东西来检索当前的StackFrame
并使用反射来改变最近的StackFrame
的method
字段,以模仿你正在做什么。
void Main()
{
DoSomething();
}
void DoSomething(){
Console.WriteLine (Environment.StackTrace); // Last frame: at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
var frames = new StackTrace().GetFrames();
var lastframe = frames[0]; // last frame: DoSomething at offset 100 in file:line:column <filename unknown>:0:0
var methodField = lastframe.GetType().GetField("method", BindingFlags.Instance | BindingFlags.NonPublic);
var redirectedMethod = typeof(Redirect).GetMethod("RedirectToMethod", BindingFlags.Instance | BindingFlags.Public);
methodField.SetValue(lastframe, redirectedMethod);
Console.WriteLine (frames); // last frame: RedirectToMethod at offset 100 in file:line:column <filename unknown>:0:0
Console.WriteLine (Environment.StackTrace); // last frame: at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
}
public class Redirect {
public void RedirectToMethod() { }
}
但是,再一次:这是非常脆弱的,不适用于你目前的情况。 你试图做的是相当奇特的,应该完全避免。
至于实际的解决方案:恐怕我没有任何Unity经验,所以我只能谷歌,但这个线程可能会让你感兴趣。 我在这里提到了.NET源代码,但你可以在Mono源程序中找到非常类似的代码。
一个解决这个问题的方法是将你的Print类编译成一个兼容的Dll(我认为.Net 2)。 当双击日志时,控制台将忽略dll信息并转到Print调用的位置。
链接地址: http://www.djcxy.com/p/80819.html