Another useful debugging tool is SOS. SOS is part of the .NET Framework in version 1.1 and later. For version 1.0 of the framework, the SOS.dll debugger extension can be found at the following URL:
http://www.microsoft.com/downloads/release.asp?ReleaseID=44274.
In Visual Studio 2003, SOS can be loaded directly using the command window and the following command:
.load sos.dll
Table 16-9 lists the SOS commands.
|
COMState |
Lists COM state for each thread |
|
ClrStack |
Provides true managed stack trace, source, and line numbers; additional parameters are -p[arams] -l[ocals] -r[egs] -a[ll] |
|
DumpClass <addr> |
Dumps EE class information |
|
DumpDomain [<addr>] |
Lists assemblies and modules in a domain |
|
DumpHeap [-stat] [-min 100] [-max 2000] [-mt 0x3000000] [-type <partial type name>] [-fix] [start [end]] |
Dumps GC heap contents |
|
DumpMD <addr> |
Dumps method description information |
|
DumpMT [-MD] <addr> |
Dumps method table information |
|
DumpModule <addr> |
Dumps EE module information |
|
DumpObj <addr> |
Dumps an object on GC heap |
|
DumpStack [-EE] [-smart] [top stack [bottom stack] |
EE shows only managed stack items |
|
DumpStackObjects [top stack [bottom stack] |
Dumps managed objects on the stack |
|
DumpVC <mt> <addr> |
Dumps a value class object |
|
EEHeap [-gc] [-win32] [-loader] |
Lists GC/loader heap information |
|
EEStack [-short] [-EE] |
Lists all stacks EE knows |
|
EEVersion |
Lists mscoree.dll version |
|
COMState |
Lists COM state for each thread |
|
FinalizeQueue [-detail] |
Works queue for finalize thread |
|
GCInfo [<MD>] [IP] |
Dumps GC encoding information for a managed method |
|
GCRoot <addr> |
Finds roots on stack/handle for object |
|
IP2MD <addr> |
Finds method description from IP |
|
Name2EE <module name> <item name> |
Finds memory address of EE data given a class/method name |
|
ObjSize [<addr>] |
Finds number of bytes that a root or all roots keep alive on GC heap |
|
ProcInfo [-env] [-time] [-mem] |
Displays the process information |
|
RWLock [-all] <addr> |
Lists information for a Read/Write lock |
|
SyncBlk [-all|#] |
Lists synchronize block |
|
ThreadPool |
Displays CLR thread pool state |
|
Threads |
Lists managed threads |
|
Token2EE <module name> <mdToken> |
Finds memory address of EE data for metadata token |
|
u [<MD>] [IP] |
Unassembles managed code |
The following sections provide examples of using many of the SOS commands listed in Table 16-9.
The !COMState command returns the COM apartment state for each thread in the process.
!comstate ID TEB APT APTId CallerTID Context 3040 be0 7ffde000 Ukn 2096 830 7ffdc000 Ukn 2468 9a4 7ffdb000 MTA 0 0 00168e60 756 2f4 7ffda000 Ukn 2560 a00 7ffd9000 MTA 0 0 00168e60
The !ClrStack command dumps the managed stack for the thread.
0:003> !clrstack -smart Thread 3 ESP EIP 06e3fbc8 7ffe0304 [FRAME: GCFrame] 06e3fc7c 7ffe0304 [FRAME: HelperMethodFrame] 06e3fca8 06d30242 [DEFAULT] [hasThis] Void Test.Ch14.Deadlock.Method1() at [+0x62] [+0x2e] c:\class\test\ch14\deadlock.cs:39 06e3fed4 791da717 [FRAME: GCFrame]
The !DumpClass <addr> command dumps the managed class information.
!dumpclass 79c0d20c Class Name : System.Collections.Hashtable mdToken : 020000f9 (Fusion.DLL) Parent Class : 79bf83c8 ClassLoader : 0014e970 Method Table : 79c0d0cc Vtable Slots : 1c Total Method Slots : 38 Class Attributes : 102001 : Flags : 3000821 NumInstanceFields: b NumStaticFields: 1 ThreadStaticOffset: 0 ThreadStaticsSize: 0 ContextStaticOffset: 0 ContextStaticsSize: 0 FieldDesc*: 79c0d270 MT Field Offset Type Attr Value Name 79c0d0cc 4000395 4 CLASS instance buckets 79c0d0cc 4000396 1c System.Int32 instance count 79c0d0cc 4000397 20 System.Int32 instance occupancy 79c0d0cc 4000398 24 System.Int32 instance loadsize 79c0d0cc 4000399 28 System.Single instance loadFactor 79c0d0cc 400039a 2c System.Int32 instance version 79c0d0cc 400039b 8 CLASS instance keys 79c0d0cc 400039c c CLASS instance values 79c0d0cc 400039d 10 CLASS instance _hcp 79c0d0cc 400039e 14 CLASS instance _comparer 79c0d0cc 400039f 18 CLASS instance m_siInfo 79c0d0cc 4000394 0 CLASS shared static primes
The address required for this can be acquired by using !DumpMT on the class.
!dumpmt 79c0d0cc EEClass : 79c0d20c Module : 79be2000 Name: System.Collections.Hashtable mdToken: 020000f9 (c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll) MethodTable Flags : 2040000 Number of IFaces in IFaceMap : 6 Interface Map : 79c0d1dc Slots in VTable : 56
The !DumpDomain <addr> command shows the assemblies and modules in the domain. (You can get the application domain addresses by using the !Threads command.)
0:000> !dumpdomain -------------------------------------- System Domain: 793e6fc8 LowFrequencyHeap: 793e702c HighFrequencyHeap: 793e7080 StubHeap: 793e70d4 Name: Assembly: 00157a10 [mscorlib] ClassLoader: 00157ae8 Module Name 79b66000 c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll -------------------------------------- Shared Domain: 793e83f8 LowFrequencyHeap: 793e845c HighFrequencyHeap: 793e84b0 StubHeap: 793e8504 Assembly: 00157a10 [mscorlib] ClassLoader: 00157ae8 Module Name 79b66000 c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll -------------------------------------- Domain 1: 146320 LowFrequencyHeap: 00146384 HighFrequencyHeap: 001463d8 StubHeap: 0014642c Name: Test.exe Assembly: 001605d0 [Test] ClassLoader: 001606a8 Module Name 00160178 C:\class\Test\bin\Debug\Test.exe
The !DumpHeap [-stat] [-min 100] [-max 2000] [-mt 0x30000000] [-fix] [start [end]] command displays the contents of the managed heap. The options are as follows:
|
-stat |
Show only statistics |
|
-min <#> |
Show only objects that are larger than # bytes |
|
-max <#> |
Show only objects that are smaller than # bytes |
|
-mt <addr> |
Show only objects with a particular method table |
!dumpheap -stat
Last good object: 04a43268
total 143 objects
Statistics
MT Count TotalSize Class Name
79bcf944 1 12 System.Runtime.Remoting.
Messaging.CallContextSecurityData
79b87458 1 12 System.IO.Stream/NullStream
3e50cc 1 16 Test.Ch14.Deadlock
79bba67c 1 20 System.Text.UTF8Encoding/UTF8Encoder
79bba3c4 1 20 System.IO.TextWriter/NullTextWriter
79bba114 1 20 System.Text.CodePageEncoding
79b8b7b4 1 20 System.Collections.ArrayList
79b87efc 1 20 System.Text.UTF8Encoding
79b830a4 1 20 System.AppDomainSetup
79bcea2c 1 28
System.Runtime.Remoting.Messaging.LogicalCallContext
79b80b44 1 32 System.SharedStatics
79be58d4 2 40 System.IO.__ConsoleStream
79b7f4f4 2 40 System.Text.StringBuilder
3e5174 2 40 Test.Ch14.Resources
79b802dc 1 64 System.StackOverflowException
79b801a4 1 64 System.OutOfMemoryException
79b81bec 1 80 System.AppDomain
14d5d0 5 6124 Free
93209c 4 6312 System.Object[]
Total 143 objects
large objects
Address MT Size
90d9350 79b4f3f8 87492 System.String
90c3df8 79b4f3f8 87360 System.String
90ae928 79b4f3f8 87224 System.String
total XX large objects
You can also scan the managed heap for a specific object by using !DumpHeap –mt <MT address>.
0:005> !dumpheap -mt 3e50cc
Address MT Size
04a41ad0 003e50cc 16
Bad MethodTable for Obj at 04a432a4
Last good object: 04a43268
total 1 objects
Statistics
MT Count TotalSize Class Name
3e50cc 1 16 Test.Ch14.Deadlock
Total 1 objects
The !DumpMD <addr> command shows method description information.
0:005> !dumpmd 79b7c530 Method Name : [DEFAULT] [hasThis] Void System.Object.Finalize() MethodTable 79b7c364 Module: 79b66000 mdToken: 0600000a (c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll) Flags : 8000 IL RVA : 00007a00
The following examples show how to set a breakpoint in managed code, both in code that has been jitted and in code that has not been jitted.
!name2ee test.Exe Test.Ch14.ThreadPoolDemo.Main -------------------------------------- MethodDesc: 3e5290 Name: [DEFAULT] I4 Test.Ch14.ThreadPoolDemo.Main() !dumpmd 3e5290 Method Name : [DEFAULT] I4 Test.Ch14.ThreadPoolDemo.Main() MethodTable 3e52c8 Module: 15d230 mdToken: 06000001 (c:\class\Test\bin\Debug\Test.exe) Flags : 10 Method VA : 06db0078 Set the breakpoint on the Method VA of 06db0078
!name2ee test.Exe Test.Ch14.ThreadPoolDemo.Main -------------------------------------- MethodDesc: 3e5290 Name: [DEFAULT] I4 Test.Ch14.ThreadPoolDemo.Main() !dumpmd 3e5290 Method Name : [DEFAULT] I4 Test.Ch14.ThreadPoolDemo.Main() MethodTable 3e52c8 Module: 15d230 mdToken: 06000001 (c:\class\Test\bin\Debug\Test.exe) Flags : 10 Method RVA : 0078 ba w4 3e5290+4 !dumpmd 3e5290 Method Name : [DEFAULT] I4 Test.Ch14.ThreadPoolDemo.Main() MethodTable 3e52c8 Module: 15d230 mdToken: 06000001 (c:\class\Test\bin\Debug\Test.exe) Flags : 10 Method VA : 06db0078 Bp 06db0078
The !DumpMT [-MD] <addr> command dumps the managed class information. If you use the – MD switch, as in the following example, you will also get the methods that the object hosts. You can get more information on the methods by using !DumpMD <addr>.
0:005> !dumpmt -MD 3e5174 EEClass : 06c037d0 Module : 00160178 Name: Test.Ch14.Resources mdToken: 02000002 (C:\class\Test\bin\Debug\Test.exe) MethodTable Flags : c0000 Number of IFaces in IFaceMap : 0 Interface Map : 003e51b4 Slots in VTable : 5 --------------------------------------- MethodDesc Table Entry MethodDesc JIT Name 79b7c4eb 79b7c4f0 None [DEFAULT] [hasThis] String System.Object.ToString() 79b7c473 79b7c478 None [DEFAULT] [hasThis] Boolean System.Object.Equals(Object) 79b7c48b 79b7c490 None [DEFAULT] [hasThis] I4 System.Object.GetHashCode() 79b7c52b 79b7c530 None [DEFAULT] [hasThis] Void System.Object.Finalize() 003e515b 003e5160 None [DEFAULT] [hasThis] Void Test.Ch14.Resources..ctor()
The !DumpModule <addr> command shows EE module information.
0:000> !dumpmodule 00160178 Name C:\class\Test\bin\Debug\Test.exe dwFlags 00003280 Attribute PEFile Edit&Continue Assembly 001605d0 LoaderHeap* 001601f8 TypeDefToMethodTableMap* 06bf0010 TypeRefToMethodTableMap* 06bf001c MethodDefToDescMap* 06bf0038 FieldDefToDescMap* 06bf0050 MemberRefToDescMap* 06bf0068 FileReferencesMap* 06bf0090 AssemblyReferencesMap* 06bf0094 MetaData starts at 00402260 (0x428 bytes)
The !DumpObj <addr> command shows an object on the GC heap.
0:000> !dumpobj 04a41ad0
Name: Test.Ch14.Deadlock
MethodTable 0x003e50cc
EEClass 0x06c032e8
Size 16(0x10) bytes
mdToken: 02000003 (C:\class\Test\bin\Debug\Test.exe)
FieldDesc*: 003e5058
MT Field Offset Type Attr Value Name
003e50cc 4000004 4 CLASS instance 04a41ae0 Resource1
003e50cc 4000005 8 CLASS instance 04a41b48 Resource2
The !DumpStack [-EE] [-smart] [<top stack> [<bottom stack>]] command shows managed stack items.
0:000> !dumpstackobjects 0012f690 06db0118 (MethodDesc 0x3e5280 +0xc0 TheTraceSwitch.TracingExample.Main)
The !DumpStackObjects [<top stack>[<bottom stack>]] command dumps all the managed objects on the stack.
!dumpstackobjects ESP/REG Object Name 0012f2fc 04aaa810 System.Diagnostics.TraceSwitch 0012f320 04aaa810 System.Diagnostics.TraceSwitch 0012f328 04a52bf4 System.Diagnostics.TraceSwitch 0012f37c 04aaa7e8 System.String logfilename 0012f380 04aaa7e8 System.String logfilename 0012f3bc 04aaa810 System.Diagnostics.TraceSwitch 0012f460 04aaa810 System.Diagnostics.TraceSwitch 0012f464 04a52bf4 System.Diagnostics.TraceSwitch 0012f468 04aaa810 System.Diagnostics.TraceSwitch 0012f470 04aaa810 System.Diagnostics.TraceSwitch 0012f474 04a528e4 System.String Application Switch 0012f6a4 04a4a43c System.Object[] 0012f6d8 04a4a43c System.Object[] 0012f928 04a4a43c System.Object[] 0012f92c 04a4a43c System.Object[]
The !EEVersion command shows the version of mscoree.dll in use.
!eeversion 1.1.4322.573 retail Workstation build
Each generation has its own finalization queue. Objects are placed into this queue if they contain a finalizer(~ ClassName ) method. When a garbage collection cycle for a generation is started, a graph of available objects is made. When an object is found to be no longer available, it is compared to the finalization queue. If a corresponding object is found, the object is placed on the FReachable queue, which is defined as "Ready For Finalization." Objects in the FReachable queue have their finalizer called, and then they are made no longer strongly referenced, which can be seen by using !GCRoot [MT]. If results show HANDLE(STRONG), then the object is considered strongly rooted.
The !FinalizeQueue [-detail] command shows information about finalizable objects.
!finalizequeue
SyncBlock to be cleaned up: 0
----------------------------------
generation 0 has 0 finalizable objects (001559e8->001559e8)
generation 1 has 0 finalizable objects (001559e8->001559e8)
generation 2 has 0 finalizable objects (001559e8->001559e8)
Ready for finalization 0 objects (001559e8->001559e8)
Statistics
MT Count TotalSize Class Name
3e512c 1 16 Test.Ch10.FSTest
Total 1 objects
The !EEHeap –gc command shows the address of each heap.
!eeheap -gc generation 0 starts at 0x1b8eb280 generation 1 starts at 0x1b831028 generation 2 starts at 0x05061028 segment begin allocated size 05060000 05061028 0605ffbc 0x00ffef94(16773012) //Generation 2 Heap 19410000 19411028 1a3873ec 0x00f763c4(16212932) 15010000 15011028 15e65b04 0x00e54adc(15026908) 17010000 17011028 17f7c1ac 0x00f6b184(16167300) 1b830000 1b831028 1b9341f8 001031d0(1061328) //Generation 0 and 1 Heaps Large object heap starts at 0x06061028 segment begin allocated size 06060000 06061028 06d7f8e8 0x00d1e8c0(13756608) //Large Object Heap 16010000 16011028 1682b560 0x0081a538(8496440) 18010000 18011028 18fe4288 0x00fd3260(16593504) Total Size 0x63441e0(104088032) ----------------------------- GC Heap Size 0x63441e0(104088032)
The !GCRoot <addr> command shows the roots on the stack and handle for an object.
0:003> !gcroot 04a41ad0 Scan Thread 0 (a0c) Scan Thread 1 (eac) Scan Thread 3 (150) ESP:6e3fcbc:Root:04a41ad0(Test.Ch14.Deadlock) ESP:6e3fd04:Root:04a41b5c(System.Threading.ThreadStart)->04a41ad0( Test.Ch14.Deadlock) ESP:6e3ff00:Root:04a41b5c(System.Threading.ThreadStart)->04a41ad0( Test.Ch14.Deadlock) ESP:6e3ff08:Root:04a41b5c(System.Threading.ThreadStart)->04a41ad0( Test.Ch14.Deadlock) Scan Thread 4 (cfc) ESP:6f3fcbc:Root:04a41ad0(Test.Ch14.Deadlock)->04a41ad0(Test.Ch14.Deadlock) ESP:6f3fd04:Root:04a41f9c(System.Threading.ThreadStart)->04a41ad0( Test.Ch14.Deadlock) ESP:6f3ff00:Root:04a41f9c(System.Threading.ThreadStart)->04a41ad0( Test.Ch14.Deadlock) ESP:6f3ff08:Root:04a41f9c(System.Threading.ThreadStart)->04a41ad0( Test.Ch14.Deadlock) Scan HandleTable 148240 Scan HandleTable 149650
The !Name2EE <module name> <item name> command shows the memory address of EE data given a class and method name.
0:003> !name2ee Test.exe Test.Ch14.Deadlock.Main ----------------------------------------- MethodDesc: 3e5088 Name: [DEFAULT] I4 Test.Ch14.Deadlock.Main()
The !ObjSize [<addr>] command shows the number of bytes that a root (or all roots) keep alive on the GC heap.
0:001> !ObjSize 010a50e0 sizeof(010a50e0) = 28 ( 0x1c) bytes (Behavior1.Behavior1)
The !SyncBlk [-all|<#>] command shows synchronization blocks.
!syncblk -all
Index SyncBlock MonitorHeld Recursion Thread ThreadID Object Waiting
1 00000000 04a42678
2 00167d84 0 0 0 none 04a4a4e4
System.Threading.Thread
3 00167db0 0 0 0 none 04a4a558
System.Threading.Thread
4 00167ddc 3 1 1679f0 274 628 04a4a44c
Test.Ch14.Resources
5 00167e08 3 1 167bb8 8082056 04a4a4b4
Test.Ch14.Resources
-----------------------------
Total 6
ComCallWrapper 0
ComPlusWrapper 0
ComClassFactory 0
Free 0
The !ThreadPool command does many things for you. It tells you the current processor utilization, as well as the number of items in the queue. In addition, it shows statistics about the thread pool and I/O threads.
!ThreadPool CPU utilization 44% Worker Thread: Total: 2 Running: 2 Idle: 0 MaxLimit: 25 MinLimit: 1 Work Request in Queue: 7 QueueUserWorkItemCallback DelegateInfo@0016ce40 QueueUserWorkItemCallback DelegateInfo@0016d098 QueueUserWorkItemCallback DelegateInfo@0016d618 QueueUserWorkItemCallback DelegateInfo@0016d990 QueueUserWorkItemCallback DelegateInfo@0016d900 QueueUserWorkItemCallback DelegateInfo@0016d870 QueueUserWorkItemCallback DelegateInfo@0015da98 -------------------------------------- Number of Timers: 0 -------------------------------------- Completion Port Thread: Total: 0 Free: 0 MaxFree: 2 CurrentLimit: 0 MaxLimit: 1000 MinLimit: 1
The !Threads command shows managed threads.
!Threads
ThreadCount: 4
UnstartedThread: 0
BackgroundThread: 3
PendingThread: 0
DeadThread: 0
PreEmptive GC Alloc
ID ThreadOBJ State GC Context Domain
Lock Count APT Exception
3040 be0 0014cc38 28 Enabled 00000000:00000000 00146f10
1 Ukn
2096 830 001571b0 1228 Enabled 00000000:00000000 00146f10
0 Ukn (Finalizer)
2468 9a4 0016c980 1800228 Enabled 00000000:00000000 00146f10
2 MTA (Threadpool Worker)
2560 a00 0016dee8 3800228 Enabled 00000000:00000000 00146f10
0 MTA (Threadpool Worker)