【问题标题】:What does fields in method table mean in this example?在这个例子中方法表中的字段是什么意思?
【发布时间】:2010-11-05 07:18:13
【问题描述】:

我正在尝试了解存储在方法表中的信息。这是我的代码。

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. 这个表示继承方法的个数,指向父对象类方法ToStringEqualsGetHashCodeFinalize。这是正确的吗?

我不了解其他领域,所以如果有人也解释一下,将不胜感激。

【问题讨论】:

    标签: c# clr windbg sos


    【解决方案1】:

    这基本上是一个实现细节,至少可以说,试图通过探索内部结构来弄清楚 CLR 是如何工作的并不容易。许多内部结构都以各种方式进行了优化,这使得转储相关信息变得困难。我有一个similar question here

    如果您还没有看过它,我建议您阅读Shared Source CLI essentials。虽然它没有涵盖所有血淋淋的细节,但它确实很好地解释了共享源 CLI 的组织方式。

    根据我的经验,如果不使用封装 CLR 在内部执行的操作的实用方法,就无法轻松映射其中一些结构。这基本上就是 SOS 为我们所做的。如果您获得了SSCLI 的源代码,您可以深入了解 SOS 的共享源代码版本的源代码以获取更多详细信息。

    当然,SSCLI 与当前的 Microsoft CLR 不同,但根据我的经验,它们有很多共同点,因此它通常是一个很好的信息来源。

    详细描述了方法表是如何在 .NET 1.x here 中实现的。它有很多细节,但是可惜实现已经改变,所以它对当前的 CLR 无效。

    【讨论】:

    • 感谢布赖恩的回复。这些字段在 Advanced .NET Debugging book 中有描述,但由于某种原因,我得到的值与书中描述的不同;我希望有人可以解释可能导致差异的原因。
    【解决方案2】:

    随便用

    !sos.dumpmt 001f3310
    

    这将为您提供方法表转储,您不必担心会在版本和 SP 之间更改的内部内存布局

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      • 1970-01-01
      相关资源
      最近更新 更多