.net clr 方法 table 结构
.net clr method table structure
我目前正在阅读名为 Pro .NET Performance 的书。其中一章包含有关引用类型内部结构的详细信息。方法table是引用类型布局结构的内部字段之一。在这本书中说,方法 table 包含有关 class 的所有方法的信息。我正在尝试用一个小程序来验证这个理论
class MyClass
{
public void M()
{
}
}
static void Main(string[] args)
{
MyClass m = new MyClass();
m.M();
Console.ReadLine();
}
我用 WinDbg 启动这个程序
我的 WinDbg 会话如下所示
!clrstack -a
ConsoleApp.Program.Main(System.String[]) [c:\visual studio 2012\Projects\Algorithms\ConsoleApp\Program.cs @ 36]
PARAMETERS:
args (0x00bff274) = 0x02ba2fbc
LOCALS:
0x00bff270 = 0x02ba2fd8
0x02ba2fd8 - 是MyClass实例的地址
我接下来要做的是尝试转储 MyClass 实例
!do 0x02ba2fd8
Name: ConsoleApp.MyClass
MethodTable: 00f84d74
EEClass: 00f81840
Size: 12(0xc) bytes
File: C:\visual studio 2012\Projects\Algorithms\ConsoleApp\bin\Debug\ConsoleApp.exe
Fields:
MT Field Offset Type VT Attr Value Name
601a4544 4000001 4 System.Int32 1 instance 10 Z
下一步是转储方法table(它的地址是00f84d74)
!dumpmt -md 00f84d74
EEClass: 00f81840
Module: 00f83fbc
Name: ConsoleApp.MyClass
mdToken: 02000002
File: C:\visual studio 2012\Projects\Algorithms\ConsoleApp\bin\Debug\ConsoleApp.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 6
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
6005a2c8 5fcf8354 PreJIT System.Object.ToString()
60065600 5fcf835c PreJIT System.Object.Equals(System.Object)
600319b0 5fcf837c PreJIT System.Object.GetHashCode()
600316e8 5fcf8390 PreJIT System.Object.Finalize()
012604c0 00f84d6c JIT ConsoleApp.MyClass..ctor()
012604f8 00f84d60 JIT ConsoleApp.MyClass.M()
!dumpmt 命令的输出显示方法 table 包含 M() 方法的条目。但是当我尝试在地址 00f84d74
处转储内存时
dd 00f84d74
00f84d74 00000200 0000000c 00024188 00000004
00f84d84 601a299c 00f83fbc 00f84db0 00f81840
00f84d94 012604c0 00000000 00f84da0 6005a2c8
00f84da4 60065600 600319b0 600316e8 00000080
00f84db4 00000000 03ba3500 00000000 03ba3504
00f84dc4 00000000 00000000 00000000 00000000
00f84dd4 00000000 00000000 00000000 00000000
00f84de4 00000000 00000000 00000000 00000000
我找不到任何对 M() 方法地址的引用 (012604f8)
所以问题是方法 table 是否包含对非虚拟方法的引用?它们存储在哪里?
感谢我的一位同事解答了我的问题。事实证明,方法指针位于相对于方法table指针
的负偏移处
我目前正在阅读名为 Pro .NET Performance 的书。其中一章包含有关引用类型内部结构的详细信息。方法table是引用类型布局结构的内部字段之一。在这本书中说,方法 table 包含有关 class 的所有方法的信息。我正在尝试用一个小程序来验证这个理论
class MyClass
{
public void M()
{
}
}
static void Main(string[] args)
{
MyClass m = new MyClass();
m.M();
Console.ReadLine();
}
我用 WinDbg 启动这个程序 我的 WinDbg 会话如下所示
!clrstack -a
ConsoleApp.Program.Main(System.String[]) [c:\visual studio 2012\Projects\Algorithms\ConsoleApp\Program.cs @ 36]
PARAMETERS:
args (0x00bff274) = 0x02ba2fbc
LOCALS:
0x00bff270 = 0x02ba2fd8
0x02ba2fd8 - 是MyClass实例的地址 我接下来要做的是尝试转储 MyClass 实例
!do 0x02ba2fd8
Name: ConsoleApp.MyClass
MethodTable: 00f84d74
EEClass: 00f81840
Size: 12(0xc) bytes
File: C:\visual studio 2012\Projects\Algorithms\ConsoleApp\bin\Debug\ConsoleApp.exe
Fields:
MT Field Offset Type VT Attr Value Name
601a4544 4000001 4 System.Int32 1 instance 10 Z
下一步是转储方法table(它的地址是00f84d74)
!dumpmt -md 00f84d74
EEClass: 00f81840
Module: 00f83fbc
Name: ConsoleApp.MyClass
mdToken: 02000002
File: C:\visual studio 2012\Projects\Algorithms\ConsoleApp\bin\Debug\ConsoleApp.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 6
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
6005a2c8 5fcf8354 PreJIT System.Object.ToString()
60065600 5fcf835c PreJIT System.Object.Equals(System.Object)
600319b0 5fcf837c PreJIT System.Object.GetHashCode()
600316e8 5fcf8390 PreJIT System.Object.Finalize()
012604c0 00f84d6c JIT ConsoleApp.MyClass..ctor()
012604f8 00f84d60 JIT ConsoleApp.MyClass.M()
!dumpmt 命令的输出显示方法 table 包含 M() 方法的条目。但是当我尝试在地址 00f84d74
处转储内存时dd 00f84d74
00f84d74 00000200 0000000c 00024188 00000004
00f84d84 601a299c 00f83fbc 00f84db0 00f81840
00f84d94 012604c0 00000000 00f84da0 6005a2c8
00f84da4 60065600 600319b0 600316e8 00000080
00f84db4 00000000 03ba3500 00000000 03ba3504
00f84dc4 00000000 00000000 00000000 00000000
00f84dd4 00000000 00000000 00000000 00000000
00f84de4 00000000 00000000 00000000 00000000
我找不到任何对 M() 方法地址的引用 (012604f8)
所以问题是方法 table 是否包含对非虚拟方法的引用?它们存储在哪里?
感谢我的一位同事解答了我的问题。事实证明,方法指针位于相对于方法table指针
的负偏移处