在WinDbg中,我使用!name2ee来查找基类的EEClass和MethodTable。 如何找到从该特定类型继承的所有实例?
最佳答案
我希望有一个简单的答案,并且其他人可以比这更容易地解决它。
背景信息
以一种可以从输出中获取地址的方式转储所有对象:
!dumpheap -short
循环所有这些对象
.foreach ( adr {!dumpheap -short}) { ... }
方法表将是对象地址处的第一个指针大小字节,因此而不是
!do <address>
要查找方法表,您还可以执行? poi(<address>)
.!dumpmt
没有列出基类,需要自己查找。在 64 位上,基类距离 16 个字节,因此要从对象地址获取基类的类型,您可以执行!dumpmt poi(poi(<address>)+0x10)
。您可以重复此操作来获取基基类:!dumpmt poi(poi(<address>)+0x10)+0x10)
.您可以重复此操作,直到指针为 0x00000000,这意味着您已到达 System.Object 并且不再有基类。
由于您想要自动化此过程,因此您还需要将其放入循环中:
r$t0 =poi(<address>); .while(@$t0) { .if(@$t0 == <basemt>) {...}; r$t0=poi(@$t0+0x10);}
对地址进行任何您想要的操作,例如只需列出它:
.echo ${adr}
或转储它:!do ${adr}
.把它们放在一起。
示例
由于我不知道您要查找什么,因此我将使用 Exception
举个例子。因为总有一个 StackOverflowException
, OutOfMemoryException
和ExecutionEngineException
在任何 .NET 程序中,如果您尝试的话,它至少应该找到三个对象。
0:021> !name2ee *!System.Exception
Module: 000007fef2091000
Assembly: mscorlib.dll
Token: 0000000002000005
MethodTable: 000007fef2776738
EEClass: 000007fef214d7b0
Name: System.Exception
所以<basemt>
我正在寻找的参数是 000007fef2776738
.
现在完整的声明(为了便于阅读而格式化):
.foreach ( adr {!dumpheap -short}) {
r$t0 =poi(${adr});
.while(@$t0) {
.if(@$t0 == 000007fef2776738) {!do ${adr}};
r$t0=poi(@$t0+0x10);
}
}
或(格式化为复制和粘贴):
.foreach ( adr {!dumpheap -short}) { r$t0 =poi(${adr}); .while(@$t0) { .if(@$t0 == 000007fef2776738) {!do ${adr}}; r$t0=poi(@$t0+0x10);} }
关于debugging - 查找所有继承自基类的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27343095/