Did you know you can build your own advanced commands using for each, if, etc? The complete list of control tokens are:
Using these command tokes you can send quite advanced instructions to the debugger that not only will make your job a lot easier, but also impress your manager immensely. :)
Let's begin with an easy example. Imagine you want to investigate all strings on the heap that are 6500 bytes or more. To list them you'd simply type !dumpheap -type System.String -min 6500. This will give you the following information:
So far, so good. The problem is that in order to investigate each string you'd have to run !dumpobject (!do) on every address. This might be acceptable now that we're only dealing with 6 strings, but what if it were 25, or 100? I don't know if you're aware of this, but if you pass the -short argument to !dumpheap it will give you the minimum information (just the addresses of the objects in question):
Now, let's use this information in a .foreach-clause:
Let's analyze the exact syntax. Here's the command
"myVariable" is, as the name implies, the name of the variable that I wish to use for the data generated by the first set of commands. The second set of commands is what I wish to execute for each token. First I run !do on the variable, and then I use the .echo-command to print a separator in order to make it a bit easier on the eyes.
There are additional parameters you can use. For example you can choose to skip every n number of variables, or specify a text file to be parsed and used as tokens instead. Take a look at the windbg documentation if you're interested.
I first saw this being used by my colleague Doug Stewart, who is a genius with these things.
What it does is, it runs !iisinfo.clientonns and uses the MS-DOS FIND-command to count the number of times the string "Request active" appears. Off course you could use it to search for certain strings from any type of output, like ".shell -i - -ci "!do 0b62e790" FIND /c /i "<table"" or whatever suits your needs.
Let's take a quick look at the syntax.
When it comes to ".shell" the -i option is mandatory. It specifies the file we want to use for input. In this scenario we don't want to use a file, so we add another hyphen, resulting in the following syntax: ".shell -i -"
We then add the -ci option, which states that we should treat the following commands as an input file instead. ".shell -i - -ci "!iisinfo.clientconns""
Finally we state what shell command we wish to run using this input. ".shell -i - -ci "!iisinfo.clientconns" FIND /c "Request active"".
Naturally we can use any complicated command we wish in the statement, so instead of !iisinfo.clientconns we could run one of our .foreach-loops instead.