Iterating through !DumpHeap output to read value a

2019-02-25 05:57发布

I'm trying to come up with a WinDbg command line expression that takes the output of the !DumpHeap command and for each address, reads a 64-bit value from offset 0x08 after the address. I think this is possible (not sure about it) but every attempt I made so far fails with some error.

I searched a lot but most WinDbg articles show simple examples which I can try but my attempts fail.

I have a process dump of an ASP.NET worker process. The process has some memory growth but there's no clear offender so I'm trying to list a number of objects that appear many times in memory. I'm using sos.dll for the managed debugging WinDbg extensions.

Here's what I'm trying to do

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

Note, that the above command must be on a single line - I only added a line break for better readability here.

For the above line, WinDbg prints this error: Couldn't resolve error at 'myaddress+0x8);!do @$t0;.echo ************* 00000001003cb870'.

I'm trying to iterate through all addresses returned by !DumpHeap - each address should go into the myaddress variable. Then, for each address, I'm trying to set the $t0 user register to the value read from myaddress+0x8. The !do (!DumpObject) command would then dump the object at that address.

If I run only (again, on one line in WinDbg):

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

I get a list of object dumps but this is one level higher than what I need. I want to drill down one level deeper and dump a particular member of these top-level objects that I'm iterating through.

Is this possible or am I on the wrong track with this?

2条回答
Explosion°爆炸
2楼-- · 2019-02-25 06:34

yes you need space around the aliases

.foreach ( place { .shell -ci "!DumpHeap -stat" sed 1,3d | awk "{print $1 }" } ) { .foreach (plays { !DumpHeap -short -mt place } ) { r $t0 = poi( plays + 8 ) ; !do @$t0 ; .echo ========================================= } }

查看更多
神经病院院长
3楼-- · 2019-02-25 06:45

After further searching, I found that I was using the wrong syntax. According to question and to MSDN, variable names must be surrounded by spaces or must be enclosed in ${...} to work. After I used the ${} enclosure, my script started working.

For future reference, here's how to run the script (keep it on one line in WinDbg):

.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r @$t0=poi(${myaddress}+0x8);!do @$t0;.echo ************* myaddress}
查看更多
登录 后发表回答