Sunday, May 26, 2013

The mystery of the inserted method

Today on FAIC, a detective story.

Suppose you have this class in assembly Alpha.DLL:

namespace Alpha
{
    public class Bravo
    {
        public void Charlie()
        {
            System.Console.WriteLine("Alpha Bravo Charlie");
        }
    }
}

Pretty straightforward. You call this method from assembly Delta.EXE like this:

namespace Delta
{
    public interface IFoxtrot
    {
        void Charlie();
    }
    public class Echo : Alpha.Bravo, IFoxtrot
    {
    }
    public class Program
    {
        static void Main()
        {
            IFoxtrot foxtrot = new Echo();
            foxtrot.Charlie();
        }
    }
}

Notice that class Echo does not re-implement Charlie, but that's fine; the base class implementation suffices to meet the requirements of interface IFoxtrot. If we run this code and put a breakpoint on Charlie the call stack window in Visual Studio says:

Alpha.dll!Alpha.Bravo.Charlie()
[External Code]
Delta.exe!Delta.Program.Main()
[External Code]

It's unsurprising that there is "external code" inserted that calls Main for you, but what's with the "external code" between Main and Charlie? That should just be a straight call, right? Something strange is going on here.

It is possible for debugging purposes to programmatically inspect the call stack1 so let's change the implementation of Charlie to print out the caller. This let's us do a bit of an end-run around the debugger2 to see what is really happening there:

public void Charlie()
{
    System.Console.WriteLine("Alpha Bravo Charlie");
    System.Console.WriteLine((new      System.Diagnostics.StackFrame(1).GetMethod().Name));
}

QR: Inline image 1