【问题标题】:Running a command from the loop从循环中运行命令
【发布时间】:2015-11-12 16:34:39
【问题描述】:

我想从以下命令对每个地址运行 !refs 命令

!dumpgen 2 -type System.DateTime[]

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

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

但是我怎样才能访问可以使用 !refs 循环使用的对象地址?

【问题讨论】:

    标签: windbg sos sosex


    【解决方案1】:

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

    方法一:手动转储一代

    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. !dumpheap 上使用-short 参数,它只输出地址。对象的这个地址然后可以被其他命令处理。

    另请注意:使用-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. 根据生成,执行命令

    这里是怎么做的(为了可读性而格式化,把它全部放在一行中):

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

    其中53ab0d48 是您要查找的类型的方法表,"2" 是您想要的一代。 /pS 1!gcgen 的输出中跳过单词“Gen”。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-07
      • 2012-10-16
      • 2017-09-16
      • 2014-04-08
      • 1970-01-01
      • 2014-07-31
      相关资源
      最近更新 更多