如何使用SOS(或SOSEX)在WinDbg的某个字段中显示具有某些值的托管对象? [英] How to display managed objects with certain value in one of the fields in WinDbg using SOS (or SOSEX)?

查看:216
本文介绍了如何使用SOS(或SOSEX)在WinDbg的某个字段中显示具有某些值的托管对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是这样的:

  0:000> !DumpHeap-type Microsoft.Internal.ReadLock -stat 
------------------------------
堆0
总共0个对象
------------------------------
堆1
总共0个对象
------------------------------
总共2
0个对象
------------------------------
堆3
总共0个对象
------------------------------
总共0个对象
统计:
MT计数TotalSize类名称
000007fef3d14088 74247 2375904 Microsoft.Internal.ReadLock
总共74247个对象

我读这个输出的方式是我的堆上有74,247 Microsoft.Internal.ReadLock 实例。但是,其中一些可能正在收集。



我只想显示那些未收到的收藏。



例如, 0000000080f88e90 是这些对象之一的地址,它是垃圾。我知道,因为:

  0:000> !mroot 0000000080f88e90 
找不到根路径。
0:000> !refs 0000000080f88e90 -target
引用0000000080f88e90的对象(Microsoft.Internal.ReadLock):
NONE
0:000> !do 0000000080f88e90
名称:Microsoft.Internal.ReadLock
MethodTable:000007fef3d14088
EEClass:000007fef3c63410
大小:32(0x20)个字节
文件:C:\Windows \Microsoft.Net\assembly\GAC_MSIL\System.ComponentModel.Composition\v4.0_4.0.0__b77a5c561934e089\System.ComponentModel.Composition.dll
字段:
MT字段偏移类型VT Attr值名称
000007fef3d13fb0 400001e 8 ... oft.Internal.Lock 0实例0000000080001010 _lock
000007fef0a8c7d8 400001f 10 System.Int32 1实例1 _isDisposed

可以看到, sosex.mroot sosex.refs 表示没有人引用它,加上倾销它的字段显示它是通过 IDisposable 来处理的,所以对象是垃圾是有意义的(我知道是处置并不意味着物体是垃圾,但在这种情况下)。



现在我想显示所有不是垃圾的实例。我想我要使用 .foreach 命令。这样做:

  .foreach(entry {!dumpheap-type Microsoft.Internal.ReadLock -short}){。if ???){.printf%p\\\
,entry}}

我的问题是我不知道进入 .if 条件。



我可以检查这个_isDisposed字段:

  0:000> dd 0000000080f88e90 + 10 L1 
00000000`80f88ea0 00000001

。如果期望一个表达式,并且我所有的都是一个命令输出。如果我知道如何从命令输出中提取信息并将其排列为表达式,那么我可以使用它作为 .if 条件并且很好。



所以,我的问题是 - 有没有办法把字段值作为适合 .if 的表达式?或者,是否可以以适合使用结果的方式解析命令输出作为 .if 条件?

解决方案

我没有使用ReadLock对象的例子,但是我尝试使用Strings,这是我的结果:

  .foreach(entry {!dumpheap -short-type Microsoft.Internal.ReadLock})
{
.if(poi($ {entry} +10)== 1)
{
.printf%p\\\
,$ {entry}
}
}

我正在使用poi()从地址获取指针大小数据。另请注意,我正在使用poi()和.printf中的 $ {entry} 条目。您可能也希望在.if。$ / $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

  .foreach(entry {!dumpheap -short-type Microsoft.Internal.ReadLock}){.if(poi($ {entry} +10)== 1){.printf %p\\\
,$ {entry}}}


My problem is this:

0:000> !DumpHeap -type Microsoft.Internal.ReadLock -stat
------------------------------
Heap 0
total 0 objects
------------------------------
Heap 1
total 0 objects
------------------------------
Heap 2
total 0 objects
------------------------------
Heap 3
total 0 objects
------------------------------
total 0 objects
Statistics:
              MT    Count    TotalSize Class Name
000007fef3d14088    74247      2375904 Microsoft.Internal.ReadLock
Total 74247 objects

The way I read this output is that I have 74,247 Microsoft.Internal.ReadLock instances on my heap. However, some of them are probably pending collection.

I want to display only those which are not pending collection.

For example, 0000000080f88e90 is the address of one of these objects and it is garbage. I know it, because:

0:000> !mroot 0000000080f88e90
No root paths were found.
0:000> !refs 0000000080f88e90 -target
Objects referencing 0000000080f88e90 (Microsoft.Internal.ReadLock):
NONE
0:000> !do 0000000080f88e90
Name:        Microsoft.Internal.ReadLock
MethodTable: 000007fef3d14088
EEClass:     000007fef3c63410
Size:        32(0x20) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.ComponentModel.Composition\v4.0_4.0.0.0__b77a5c561934e089\System.ComponentModel.Composition.dll
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
000007fef3d13fb0  400001e        8 ...oft.Internal.Lock  0 instance 0000000080001010 _lock
000007fef0a8c7d8  400001f       10         System.Int32  1 instance                1 _isDisposed

As one can see, both sosex.mroot and sosex.refs indicate no one references it, plus dumping its fields reveals that it was disposed through IDisposable, so it makes sense that the object is garbage (I know that being disposed does not imply the object is garbage, but it is in this case).

Now I want to display all those instances which are not garbage. I guess I am to use the .foreach command. Something like this:

.foreach(entry {!dumpheap -type Microsoft.Internal.ReadLock -short}){.if (???) {.printf "%p\n", entry} }

My problem is that I have no idea what goes into the .if condition.

I am able to inspect the _isDisposed field like this:

0:000> dd 0000000080f88e90+10 L1
00000000`80f88ea0  00000001

But .if expects an expression and all I have is a command output. If I knew how to extract information from the command output and arrange it as an expression then I could use it as the .if condition and be good.

So, my question is this - is there a way to get the field value as an expression suitable for .if? Alternatively, is it possible to parse the command output in a way suitable for using the result as the .if condition?

解决方案

I didn't have an example which uses ReadLock objects, but I tried with Strings and this is my result:

.foreach (entry {!dumpheap -short -type Microsoft.Internal.ReadLock}) 
{ 
    .if (poi(${entry}+10) == 1)  
    {
         .printf "%p\n", ${entry}
    }
}

I'm using poi() to get pointer size data from the address. Also note I'm using ${entry} not entry in both, poi() and .printf. You might also like !do ${entry} inside the .if.

In one line for copy/paste:

.foreach (entry {!dumpheap -short -type Microsoft.Internal.ReadLock}) {.if (poi(${entry}+10) == 1) {.printf "%p\n", ${entry}}}

这篇关于如何使用SOS(或SOSEX)在WinDbg的某个字段中显示具有某些值的托管对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆