迭代通过!DumpHeap输出读取内存偏移量的值

时间:2015-01-23 03:45:42

标签: asp.net memory-leaks clr windbg crash-dumps

我正在尝试使用WinDbg命令行表达式来获取!DumpHeap命令的输出,并且对于每个地址,从地址后的偏移0x08读取64位值。我认为这是可能的(不确定),但到目前为止我所做的每一次尝试都失败了。

我搜索了很多,但大多数WinDbg文章都显示了我可以尝试的简单示例,但我的尝试失败了。

我有一个ASP.NET工作进程的进程转储。这个过程有一些内存增长,但没有明确的罪犯,所以我试图列出一些在内存中出现很多次的对象。我正在使用sos.dll进行托管调试WinDbg扩展。

这是我正在尝试做的事情

.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r @$t0=poi(myaddress+0x8);!do @$t0;.echo ************* myaddress}

注意,上面的命令必须在一行上 - 我在这里只添加了一个换行符,以提高可读性。

对于上述行,WinDbg会输出此错误:Couldn't resolve error at 'myaddress+0x8);!do @$t0;.echo ************* 00000001003cb870'

我正在尝试遍历!DumpHeap返回的所有地址 - 每个地址都应该进入myaddress变量。然后,对于每个地址,我正在尝试将$t0用户寄存器设置为从myaddress+0x8读取的值。然后!do!DumpObject)命令将对象转储到该地址。

如果我只运行(再次,在WinDbg中的一行):

.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{!do myaddress;.echo ************* myaddress}

我得到了一个对象转储列表,但这比我需要的高一级。我想深入挖掘一个级别并转储我正在迭代的这些顶级对象的特定成员。

这是可能的,还是我错了?

2 个答案:

答案 0 :(得分:4)

进一步搜索后,我发现我使用了错误的语法。根据{{​​3}}和question,变量名称必须用空格包围,或者必须包含在${...}中才能生效。使用${}附件后,我的脚本开始工作。

供将来参考,以下是如何运行脚本(将其保存在WinDbg中的一行):

.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r @$t0=poi(${myaddress}+0x8);!do @$t0;.echo ************* myaddress}

答案 1 :(得分:1)

是的,您需要在别名周围留出空间

  

.foreach(place {.shell -ci“!DumpHeap -stat”sed 1,3d | awk“{print   $ 1}“}){。foreach(plays {!DumpHeap -short -mt place}){r $ t0 =   poi(play + 8); !做@ $ t0; 。回声   =========================================}}