Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The approach you will take for debugging crashes is very similar between looking at the live process vs looking at a crash dump, there are some small differences that I will talk about in this post.
The first question: What is wrong?
If the program is throwing an exception and exiting
If the program has just crashed, the easiest thing to do it to attach a debugger to the process and see the last exception in the stack
0:005> .loadby sos clr
The !threads command will show me all threads, the thread with an exception will have an exception on top of the stack
0:005> !threads
PDB symbol for clr.dll not loaded
ThreadCount: 2
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
Lock
ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception
0 1 14d0 00492eb8 2a020 Preemptive 02639428:00000000 00483e38 0 MTA System.InvalidOperationException 024f2968
3 2 14f8 0049dd78 2b220 Preemptive 00000000:00000000 00483e38 0 MTA (Finalizer)
Now we use the !pe command to dump the exception object
0:005> !pe 024f2968
Exception object: 024f2968
Exception type: System.InvalidOperationException
Message: Path does not exist!
InnerException: <none>
StackTrace (generated):
SP IP Function
001FECE8 00520155 CompareCSV!CompareCSV.Program.Main(System.String[])+0xd5
StackTraceString: <none>
HResult: 80131509
Ok, now we know that it is a path does not exist exception, but which path? We can do this in two ways, if it is a small program like the one I have here I could do !dso
0:000> !dso
OS Thread Id: 0x11fc (0)
ESP/REG Object Name
001FEB88 024f2968 System.InvalidOperationException
001FEBD0 024f2968 System.InvalidOperationException
001FEC20 024f22a4 System.Object[] (System.String[])
001FEC50 024f22a4 System.Object[] (System.String[])
001FEC98 024f22a4 System.Object[] (System.String[])
001FECA8 024f22bc System.String c:\invalid1
001FECC8 024f2968 System.InvalidOperationException
001FECCC 024f2968 System.InvalidOperationException
001FECE8 024f29bc System.String Path does not exist!
001FECEC 024f2968 System.InvalidOperationException
001FECF8 024f22a4 System.Object[] (System.String[])
001FED90 024f22a4 System.Object[] (System.String[])
001FEEF4 024f22a4 System.Object[] (System.String[])
001FEF2C 024f22a4 System.Object[] (System.String[])
Another way to do this would be showing the CLRStack with the parameters
0:000> !clrstack -p
OS Thread Id: 0x11fc (0)
Child SP IP Call Site
001fec2c 7613b9bc [HelperMethodFrame: 001fec2c]
001fece8 00520155 CompareCSV.Program.Main(System.String[]) [d:\Projects\CompareCSV\CompareCSV\Program.cs @ 25]
PARAMETERS:
args (0x001fecf8) = 0x024f22a4
And now I can dump the args passed to main, the !do command will not be very helpful since it is an array
0:000> !do 0x024f22a4
Name: System.String[]
MethodTable: 6b4dfc38
EEClass: 6b1b7a50
Size: 24(0x18) bytes
Array: Rank 1, Number of elements 2, Type CLASS
Fields:
None
The right thing to use is !da, which will list the array items
0:000> !da 0x024f22a4
Name: System.String[]
MethodTable: 6b4dfc38
EEClass: 6b1b7a50
Size: 24(0x18) bytes
Array: Rank 1, Number of elements 2, Type CLASS
Element Methodtable: 6b52cb5c
[0] 024f22bc
[1] 024f22e0
Now I can dump the objects and see the invalid paths!
0:000> !do 024f22bc
Name: System.String
MethodTable: 6b52cb5c
EEClass: 6b15431c
Size: 36(0x24) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: c:\invalid1
Fields:
MT Field Offset Type VT Attr Value Name
6b52e784 40000aa 4 System.Int32 1 instance 11 m_stringLength
6b52d564 40000ab 8 System.Char 1 instance 63 m_firstChar
6b52cb5c 40000ac c System.String 0 shared static Empty
>> Domain:Value 003f7838:NotInit <<
0:000> !do 024f22e0
Name: System.String
MethodTable: 6b52cb5c
EEClass: 6b15431c
Size: 36(0x24) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: c:\invalid2
Fields:
MT Field Offset Type VT Attr Value Name
6b52e784 40000aa 4 System.Int32 1 instance 11 m_stringLength
6b52d564 40000ab 8 System.Char 1 instance 63 m_firstChar
6b52cb5c 40000ac c System.String 0 shared static Empty
>> Domain:Value 003f7838:NotInit <<
If the program is Behaving in an unexpected way
There are various types of problems that could cause unexpected behavior, but the one I hit the most is first chance exceptions taking the code in some unexpected path, for more details check This post.
Hope you find that helpful!