在WinDbg中,我使用!name2ee 来查找基类的EEClass和MethodTable。 如何找到从该特定类型继承的所有实例?
答案 0 :(得分:10)
我希望有一个简单的答案,其他人可以比这更容易解决。
以一种可以从输出中获取地址的方式转储所有对象:!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
为例。由于在任何.NET程序中始终存在StackOverflowException
,OutOfMemoryException
和ExecutionEngineException
,因此如果您尝试它,它至少应该找到三个对象。
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);} }