如何使用SOS(或SOSEX)在WinDbg的某个字段中显示具有特定值的托管对象?

 jzcoijawlkmlzkm_307 发布于 2023-02-08 12:02

我的问题是:

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

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

我想只显示那些没有待处理的集合.

例如,0000000080f88e90是其中一个对象的地址,它是垃圾.我知道,因为:

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

正如人们可以看到的那样,sosex.mroot并且sosex.refs表明没有人引用它,加上转储它的字段显示它被处理掉了IDisposable,所以有意义的是对象是垃圾(我知道被处置并不意味着对象是垃圾,但它是在这种情况下).

现在我想显示所有那些不是垃圾的实例.我想我要使用.foreach命令.像这样的东西:

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

我的问题是我不知道是什么.if情况.

我能够像这样检查_isDisposed字段:

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

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

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

1 个回答
  • 我没有使用ReadLock对象的示例,但我尝试使用Strings,这是我的结果:

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

    我正在使用poi()从地址获取指针大小数据.另请注意,我在$ {entry}中都没有输入 poi()和.printf.您可能也喜欢!在.if中执行$ {entry}.

    在一行中复制/粘贴:

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

    2023-02-08 12:04 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有