查找从基类继承的所有实例

时间:2014-12-07 13:26:59

标签: debugging clr windbg sos

在WinDbg中,我使用!name2ee 来查找基类的EEClass和MethodTable。 如何找到从该特定类型继承的所有实例?

1 个答案:

答案 0 :(得分:10)

我希望有一个简单的答案,其他人可以比这更容易解决。

背景资料

  1. 以一种可以从输出中获取地址的方式转储所有对象:!dumpheap -short

  2. 循环遍历所有这些对象.foreach ( adr {!dumpheap -short}) { ... }

  3. 方法表将是对象地址的第一个指针大小字节,因此代替!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);}

  4. 用地址做任何你想做的事,例如:只需列出它:.echo ${adr}或转储它:!do ${adr}

  5. 全部放在一起。

  6. 实施例

    由于我不知道您在寻找什么,我将以Exception为例。由于在任何.NET程序中始终存在StackOverflowExceptionOutOfMemoryExceptionExecutionEngineException,因此如果您尝试它,它至少应该找到三个对象。

    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);} }