WinDbg Extension - sos2.dll
Thursday, October 30th, 2008I went through the pain of dumping objects after objects just to see the member instance. I took a leaf out from John Robbin’s book on Managed Debugging. He also mentioned that he didn’t appreciate the fact that microsoft removed the recursive dump in .net 2.0. I wrote sos2.dll (a WinDbg extension) which supports command to dump the objects and its members recursively. It also supports 2 other commands one to dump heap by generation number and another to get the object’s generation. Please note that dumping the heap by generation is as fast as sos.dll since it loads the sos.dll to dump the sorted heap. This is really useful when you have more than one heap because you won’t have to figure out the generation start and end address for all the heaps.
Object Inspection
—————————–
ObjectGeneration (og)
DumpGenHeap (dg)
RecursiveDumpObject (rdo)
——————————
Find an Object’s GC Generation
——————————
ObjectGeneration (og)
!og <object address>
0:000> !og 023a2eac
GC Heap Generation # 2
——————————
Dump Generational Heap
——————————
DumpGenHeap (dg)
!dg -stat <generationnumber>
Dump all the objects on heap for Generation # 1
0:000> !dg 1
Dump the statistical summay for Generation # 2
0:000> !dg -stat 2
Dump the statistical summay for Generation # 2
0:000> !dg -stat
Dump all the objects on heap for Generation # 2
(By Default, it will dump all the objects on generation #2 because that’s what usually we look at)
——————————
Object Inspection Recursively
——————————
RecursiveDumpObject (rdo)
!rdo [-nofields] <object address> < recursion level>
This command allows you to examine the fields of an object, as well as view the properties of the object such as the EEClass, the MethodTable, and the size. This command works same as !DumpObj from sos.dll but it also allows you to dump the member of the objects with recursion level option, otherwise you will have to keep running !DumpObj command with member instance address If you specify no recursion level or 0, it will just dump an object on managed heap same as DumpObj as shown below
0:000> !rdo 01cd17ec
Name: SOS2TestHarness.Oregon
MethodTable: 001d311c
EEClass: 001d1410
Size: 20(0×14) bytes
(C:\Dev\SOS2TestHarness.exe)
Fields:
MT Field Offset Type VT Attr Value Name
790fd8c4 4000001 4 System.String 0 instance 01cd1680 _name
001d31bc 4000002 8 …TestHarness.Ocean 0 instance 01cd1a28 _ocean
79101fe4 4000003 c …ections.Hashtable 0 instance 01cd1800 _keyValuePair
As shown Below when you specify the recursion level, it will also dump the member objects
0:000> !rdo 01cd17ec 1
Name: SOS2TestHarness.Oregon
MethodTable: 001d311c
EEClass: 001d1410
Size: 20(0×14) bytes
(C:\Dev\SOS2TestHarness.exe)
Fields:
MT Field Offset Type VT Attr Value Name
790fd8c4 4000001 4 System.String 0 instance 01cd1680 _name
****** Dump _name(member instance) *******
Name: System.String
MethodTable: 790fd8c4
EEClass: 790fd824
Size: 32(0×20) bytes
(C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: Pacific
Fields:
MT Field Offset Type VT Attr Value Name
……………………………………………………………….
001d31bc 4000002 8 …TestHarness.Ocean 0 instance 01cd1a28 _ocean
****** Dump _ocean(member instance) *******
Name: SOS2TestHarness.Ocean
MethodTable: 001d31bc
EEClass: 001d1474
Size: 12(0xc) bytes
(C:\Dev\SOS2TestHarness.exe)
Fields:
MT Field Offset Type VT Attr Value Name
001d324c 4000004 4 …TestHarness.River 0 instance 01cd1a34 _river
79101fe4 4000003 c …ections.Hashtable 0 instance 01cd1800 _keyValuePair
****** Dump _keyValuePair(member instance) *******
Name: System.Collections.Hashtable
MethodTable: 79101fe4
EEClass: 79101f74
Size: 56(0×38) bytes
(C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
7912d9bc 400092b 4 …ashtable+bucket[] 0 instance 01cd1838 buckets
79102290 400092c 1c System.Int32 0 instance 2 count
………………………………………………………………….