Consider the following C# code:
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" });
}
}
When I run it in either Visual Studio 2008 or Visual Studio 2008 and hit a breakpoint I put inside the “Print” method, I get the following in the callstack window:
ConsoleApplication4.exe!ConsoleApplication4.Program.Print(string
toPrint)[Native to Managed Transition]
[Managed to Native Transition]
ConsoleApplication4.exe!ConsoleApplication4.Program.Main(string[]
args)
Why doesn’t RuntimeMethodInfo.Invoke show up in my callstack? It is a managed method, after all, so why don’t I see it as I would expect?
Also, in general, what are the rules here? Which managed methods can I expect to be missing from my callstack?
The reason is that the method isn’t actually a managed method.
RunTimeMethodInfo.Invokewill eventually resolve down toRuntimeMethodHandle._InvokeMethodFastwhich is marked as anMethodImplOptions.InternalCall. This means the call is actually implemented as a helper directly in the CLR.In terms of general rules for what won’t show up in your call stack:
Just My Codeenabled (which is the default) pretty much anything you didn’t write will show up as[External Code]on the call stack.Native to ManagedandManaged to Nativetransitions on the call stack.DebuggerHidden, especially when combined with ‘just my code’ methods, but I wouldn’t necessary expect them to show up on the call stack.If you want to see the raw call stack in all of its glory then you’ll need to do the following.
Just My Code