Monday, March 16, 2009

Use .foreach to display objects

Thanks to Roberto Farah's blog on .foreach command usage, I try the command on a dump file and am impressed by its power.

0:002> !finalizequeue
SyncBlocks to be cleaned up: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
generation 0 has 88 finalizable objects (001efc68->001efdc8)
generation 1 has 19 finalizable objects (001efc1c->001efc68)
generation 2 has 77 finalizable objects (001efae8->001efc1c)
Ready for finalization 0 objects (001efdc8->001efdc8)
Statistics:
MT Count TotalSize Class Name
...
00f99444 89 4984 UtilAPI.ServerProtectionItem
Total 184 objects


0:002> !dumpheap -mt 00f99444
Address MT Size
00ffb74c 00f99444 56
01004088 00f99444 56
010044e4 00f99444 56
...
010567cc 00f99444 56
01056904 00f99444 56
total 1683 objects
Statistics:
MT Count TotalSize Class Name
00f99444 1683 94248 UtilAPI.ServerProtectionItem
Total 1683 objects

There are total 1683 ServerProtectionItem instances, and I would like to know what IP address is in each instance.

0:002> !do 00ffb74c
Name: UtilAPI.ServerProtectionItem
MethodTable: 00f99444
EEClass: 02ff7d68
Size: 56(0x38) bytes
(C:\Program Files\Ipswitch\WS_FTP Server\WrapperUtilAPI.dll)
Fields:
MT Field Offset Type VT Attr Value Name
7911d5e4 4000298 4 PTR 0 instance 00000000 m_pObj
7910bff0 40003c2 10 System.UInt32 0 instance 486 m_dwID
7910bff0 40003c3 14 System.UInt32 0 instance 1 m_dwListenerID
7910bff0 40003c4 18 System.UInt32 0 instance 68 m_dwAccessDenyFlag
7910bff0 40003c5 1c System.UInt32 0 instance 65 m_dwEntryTypeFlag
7910bff0 40003c6 20 System.UInt32 0 instance 2147483647 m_dwCountTimespanSeconds
7910c878 40003c7 24 System.DateTime 1 instance 00ffb770 m_dEntryExpires
7910c878 40003c8 2c System.DateTime 1 instance 00ffb778 m_dEntryCreated
790fd8c4 40003c9 8 System.String 0 instance 00ffb784 m_pszIPAddress
790fd8c4 40003ca c System.String 0 instance 00ffb7b4 m_pszIPMask


0:002> !do 00ffb784
Name: System.String
MethodTable: 790fd8c4
EEClass: 790fd824
Size: 46(0x2e) bytes
(C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: 89.162.184.244
Fields:
MT Field Offset Type VT Attr Value Name
79102290 4000096 4 System.Int32 0 instance 15 m_arrayLength
79102290 4000097 8 System.Int32 0 instance 14 m_stringLength
790ff328 4000098 c System.Char 0 instance 38 m_firstChar
790fd8c4 4000099 10 System.String 0 shared static Empty

To manually display the IP address in a ServerProtectionItem instance, I have to !do twice. Since there are 1683 instances, the manual approach would be time-consuming and error-prone. In this case, .foreach command comes into the rescue. Since the output of !do does not serve the purpose well, I have to figure out how to display the managed object without it.

0:002>du poi(00ffb74c+0x8)+0xc
00ffb790 "89.162.184.244"


00ffb74c is the address of a ServerProtectionItem instance, 0x8 is the offset of m_pszIPAddress in ServerProtectionItem, and 0xc is the offset of m_firstChar in System.String.

0:002> .foreach /pS 3 /ps 2 (obj {!dumpheap -mt 00f99444}) {du poi(${obj}+0x8)+0xc}
00ffb790 "89.162.184.244"
010040cc "67.214.140.63"
01004528 "216.124.168.7"
...
010566dc "166.70.91.103"
01056810 "220.130.152.65"
01056948 "218.25.86.166"
Couldn't resolve error at 'total+0x8)+0xc'


Since the output from "!dumpheap -mt 00f99444" has the following format,

Address MT Size
00ffb74c 00f99444 56
01004088 00f99444 56
010044e4 00f99444 56
...
010567cc 00f99444 56
01056904 00f99444 56
total 1683 objects


/pS 3 is used to skip the initial three tokens in red, and /ps 2 is used to skip two tokens in blue repeatedly. The error message at the end is because of the line "total 1683 objects". It seems that .foreach does not provide a way to skip the last three tokens.

0 comments:

Post a Comment