从循环中运行命令

时间:2015-11-12 16:34:39

标签: windbg sos sosex

我想从以下命令

对每个地址运行!refs命令
!dumpgen 2 -type System.DateTime[]

如何做到这一点。我知道可以按如下方式创建一个循环

.foreach (myvar {!dumpgen 2 -type System.DateTime[]}) 

但是如何通过!refs?

访问可以在循环中使用的对象地址

1 个答案:

答案 0 :(得分:2)

!dumpgen没有像-short这样的!dumpheap参数,我真的很想看到比这个更简单的答案。

方法1:手动转储一代

  1. 获取堆的地址

    0:003> !eeheap -gc
    Number of GC Heaps: 1
    generation 0 starts at 0x026f1018
    generation 1 starts at 0x026f100c
    generation 2 starts at 0x026f1000
    
  2. 使用地址将输出限制为所需的代数:

    !dumpheap -type X <start> <end>
    
  3. 使用-short上的!dumpheap参数,该参数仅输出地址。然后,可以通过其他命令处理该对象的地址。

  4. 另请注意:使用-type也可能会导致其他类型。最好将方法表与-mt一起使用,因为只保证了类型的唯一性。如果您不从其他地方获取,请使用!name2ee

    完整的会话可能如下所示:

    0:003> !dumpheap -stat
    total 345 objects
    Statistics:
          MT    Count    TotalSize Class Name
    53ab421c        1           12 System.Text.DecoderExceptionFallback
    [...]
    53ab0d48      135         6640 System.String
    53a84518       26         9452 System.Object[]
    Total 345 objects
    
    0:003> !eeheap -gc
    Number of GC Heaps: 1
    generation 0 starts at 0x026f1018
    generation 1 starts at 0x026f100c
    generation 2 starts at 0x026f1000
    [...]
    
    0:003> !name2ee *!System.String
    Module: 53841000 (mscorlib.dll)
    Token: 0x02000024
    MethodTable: 53ab0d48
    [...]
    
    0:003> !dumpheap -short -mt 53ab0d48 0x026f1000 0x026f100c
    

    (好吧,我的所有字符串似乎都在第0代,该死的: - )

    0:003> .foreach (addr {!dumpheap -short -mt 53ab0d48 0x026f1018}) {!refs ${addr}}
    

    缺点:您需要单独为所有GC堆执行此操作。可能有几个。

    方法2:决定每个单个对象的生成

    另一个丑陋的解决方案是

    1. 转储所有对象地址(!dumpheap -short-type-mt
    2. 通过!gcgen
    3. 查询每个对象的生成
    4. 根据生成,执行命令
    5. 这里是如何做到的(格式化为可读性,将其全部放在一行):

      .foreach (addr {!dumpheap -short -mt 53ab0d48}) {
          .foreach /pS 1 (gen {!gcgen ${addr}}) { 
              .if ($scmp("${gen}","2")==0) {
                  !refs ${addr}
              }
          }
      }
      

      其中53ab0d48是您要查找的类型的方法表,"2"是您想要的代数。 /pS 1跳过&#34; Gen&#34;在!gcgen的输出中。

      缺点:可能会很慢,因为它适用于所有对象。