Что означают поля в таблице методов в этом примере? - PullRequest
1 голос
/ 05 ноября 2010

Я пытаюсь понять информацию, хранящуюся в таблице методов. Вот мой код.

class MyClass
{
    private int x = 60;
    private int y = 90;

    public void MethodB() 
    {
        Console.WriteLine("MethodB");
    }

    public void MethodC()
    {
        Console.WriteLine("MethodC");
    }

    public void MethodA()
    {
        GetHashCode();


        Monitor.Enter(this);

        Console.WriteLine("Attach debugger now");
        Console.ReadKey();
    }


    static void Main(string[] args)
    {
        MyClass mc = new MyClass();
        mc.MethodA();
    }
}

Вот как выглядит объект в памяти

0:000> !do 0x02368a1c   
Name: ConsoleApplication1.MyClass  
MethodTable: 001f3310  
EEClass: 001f136c  
Size: 16(0x10) bytes  
 (C:\Download\PresentationPrep\TechDaysDemos\SomeTesting\bin\Debug\SomeTesting.exe)  
Fields:  
      MT    Field   Offset                 Type VT     Attr    Value Name  
6d032da0  4000001        4         System.Int32  1 instance       60 x  
6d032da0  4000002        8         System.Int32  1 instance       90 y  

Затем я выкидываю таблицу методов

0:000> dd 001f3310  
001f3310  00000000 00000010 00050011 00000004  
001f3320  6d030770 001f2f2c 001f334c 001f136c  
001f3330  00000000 00000000 6cf86ab0 6cf86ad0  
001f3340  6cf86b40 6cff7540 008500d0 00000080  
001f3350  00000000 00000000 00000000 00000000  
001f3360  00000000 00000000 00000000 00000000  
001f3370  00000000 00000000 00000000 00000000  
001f3380  00000000 00000000 00000000 00000000  

Вот то, что я нахожу немного запутанным.

  1. Первое поле указывает тип объекта (если это класс или массив и т. Д.). Насколько я понимаю, для класса это поле отображает 0x00040000, тогда как здесь отображается только 0x00000000.

  2. Второе поле - размер объекта. Это нормально.

  3. Какое значение имеет третье поле 00050011?

  4. Этот указывает количество унаследованных методов, которое указывает на методы класса родительского объекта ToString, Equals, GetHashCode и Finalize. Это правильно?

Я не понимаю остальных полей, поэтому, если некоторые объяснят это также, это будет высоко оценено.

Ответы [ 2 ]

1 голос
/ 20 ноября 2010

Просто используйте

!sos.dumpmt 001f3310

Это даст вам дамп таблицы методов, и вам не придется беспокоиться о разметке внутренней памяти, которая может меняться между версиями и SP

1 голос
/ 05 ноября 2010

Это в основном детали реализации, и попытка выяснить, как работает CLR, разбираясь с внутренними структурами, по меньшей мере не легко сказать. Многие внутренние структуры оптимизируются различными способами, что затрудняет передачу соответствующей информации. У меня похожий вопрос здесь .

Если вы еще не посмотрели его, я рекомендую прочитать Основы CLI Shared Source . Хотя он и не охватывает все подробности, он дает довольно хорошее объяснение того, как организован CLI с общим исходным кодом.

По моему опыту, некоторые из этих структур не могут быть легко отображены без использования служебных методов, которые инкапсулируют то, что CLR делает внутри себя. Это в основном то, что SOS делает для нас. Если вы получите исходный код SSCLI , вы можете найти дополнительную информацию в исходной версии SOS с общим исходным кодом.

Конечно, SSCLI отличается от текущего Microsoft CLR, но, по моему опыту, у них много общего, поэтому он обычно является хорошим источником информации.

Здесь подробно описано, как таблица методов была реализована в .NET 1.x здесь . В нем много деталей, но, увы, реализация была изменена, поэтому она не подходит для текущего CLR.

...