2011-07-10 25 views
2

考虑下面的C#代码:为什么RuntimeMethodInfo.Invoke不显示在我的Visual Studio调试器callstack上?

class Program 
{ 
    static public void Print(string toPrint) 
    { 
     Console.WriteLine(toPrint); 
    } 

    static void Main(string[] args) 
    { 
     Type program = typeof(Program);    
     MethodInfo methodInfo = program.GetMethod("Print", BindingFlags.Static | BindingFlags.Public); 
     methodInfo.Invoke(null, new object[] { "a" }); 
    } 
} 

当我在使用Visual  运行工作室  2008或Visual  工作室  2008年,打一个断点,我把“打印”方法中,我得到了以下调用堆栈窗口:

ConsoleApplication4.exe ConsoleApplication4.Program.Print(字符串 toPrint)

[原产于托管陈德良sition]

[托管到本机过渡]

ConsoleApplication4.exe!ConsoleApplication4.Program.Main(字符串[] 参数)

为什么不RuntimeMethodInfo.Invoke在我的调用堆栈显示?毕竟,这是一种管理方法,所以为什么我没有看到它,因为我期望?

此外,一般来说,这里的规则是什么?我可能希望从我的调用堆中丢失哪些托管方法?

回答

1

原因是该方法实际上并不是一种管理方法。 RunTimeMethodInfo.Invoke最终将解析为RuntimeMethodHandle._InvokeMethodFast,并标记为MethodImplOptions.InternalCall。这意味着该调用实际上是作为帮助者直接在CLR中实施的。

在用于调用栈究竟会不会出现的一般规律而言:

  • 如果启用Just My Code(这是默认值)相当多的东西你没有写将显示为调用堆栈上的[External Code]
  • 如果您正在进行调试管理,那么您可能会在调用堆栈中看到很多Native to ManagedManaged to Native转换。
  • 在处理内部实现的方法时,您还会在调用堆栈中看到一些模糊性。
  • 我不确定0123'的确切规则,特别是当与'我的代码'方法结合使用时,但我不希望它们出现在调用堆栈上。

如果你想看到原始调用堆栈的所有荣耀,那么你需要执行以下操作。

  • 调试管理和无启用本机调试
  • 禁用Just My Code
+0

很抱歉,但你是什么意思正是由“化解下调至”? “Invoke”和“InvokeMethodFast”没有标记为MethodImplOptions.InternalCall,只有“_InvokeMethodFast”是:我可以在Reflector中看到它们的代码。 –

+0

@Omer通过我的意思是'_InvokeMethodFast'最终将被调用。 “Invoke”和“_InvokeMethodFast”之间的所有内容都是“DebuggerHidden”,并且可能因为“Just My Code”被启用而被排除。我更新了我的答案,以获得更完整的调用堆栈 – JaredPar

+0

- 根据[此博客文章总结了DebuggerXAttributes的效果](http://blogs.msdn.com/b/stevejs/archive/2005/12 /03/499803.aspx)和我自己的测试,不管“Just My Code”是什么,DebuggerHidden方法都不会显示在callstack上。 –

相关问题