Create a deadlock Program
using System;using System.Threading;namespace ConsoleApplication1{ class Program { static void Main() { new Program().Test1(); } private void Test1() { lock (this) { Console.WriteLine("Enter Test1"); new Thread(() => { Thread.Sleep(2000); Test2(); }).Start(); Console.ReadKey(); Console.WriteLine("Exit Test1"); } } private void Test2() { lock (this) { Console.WriteLine("Test2"); } } }}
Create a. Dump File after running the program (do not click the keyboard)
Use windbg for analysis and execution ~ * E! Clrstack view all the threads holding and waiting for the lock (the next code to be executed)
0:000> ~*e!clrstackOS Thread Id: 0x26d4 (0) Child SP IP Call Site000000000045ea38 000007ffe9ab2c5a [InlinedCallFrame: 000000000045ea38] Microsoft.Win32.Win32Native.ReadConsoleInput(IntPtr, InputRecord ByRef, Int32, Int32 ByRef)000000000045ea38 000007ffd1e3f64e [InlinedCallFrame: 000000000045ea38] Microsoft.Win32.Win32Native.ReadConsoleInput(IntPtr, InputRecord ByRef, Int32, Int32 ByRef)000000000045e9f0 000007ffd1e3f64e DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, InputRecord ByRef, Int32, Int32 ByRef)000000000045eb30 000007ffd1ea9961 System.Console.ReadKey(Boolean)000000000045ec50 000007ff7b5501b1 ConsoleApplication1.Program.Test1() [f:\Documents\Visual Studio 2012\Projects\2012test\ConsoleApplication1\Program.cs @ 25]000000000045ecc0 000007ff7b5500a8 ConsoleApplication1.Program.Main() [f:\Documents\Visual Studio 2012\Projects\2012test\ConsoleApplication1\Program.cs @ 11]000000000045efd0 000007ffdac338f3 [GCFrame: 000000000045efd0] OS Thread Id: 0x2b74 (1)Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads inthe processFailed to start stack walk: 80070057OS Thread Id: 0x2a60 (2) Child SP IP Call Site000000001af8f8c8 000007ffe9ab319b [DebuggerU2MCatchHandlerFrame: 000000001af8f8c8] OS Thread Id: 0x1978 (3)Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads inthe processFailed to start stack walk: 80070057OS Thread Id: 0x242c (4) Child SP IP Call Site000000001ba6e9d8 000007ffe9ab319b [GCFrame: 000000001ba6e9d8] 000000001ba6eb18 000007ffe9ab319b [GCFrame: 000000001ba6eb18] 000000001ba6eb58 000007ffe9ab319b [HelperMethodFrame_1OBJ: 000000001ba6eb58] System.Threading.Monitor.Enter(System.Object)000000001ba6ec50 000007ff7b550300 ConsoleApplication1.Program.Test2() [f:\Documents\Visual Studio 2012\Projects\2012test\ConsoleApplication1\Program.cs @ 33]000000001ba6ecb0 000007ffd16afb65 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)000000001ba6ee10 000007ffd16af8c9 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)000000001ba6ee40 000007ffd16af887 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)000000001ba6ee90 000007ffd16c2fe1 System.Threading.ThreadHelper.ThreadStart()000000001ba6f1a8 000007ffdac338f3 [GCFrame: 000000001ba6f1a8] 000000001ba6f4d8 000007ffdac338f3 [DebuggerU2MCatchHandlerFrame: 000000001ba6f4d8]
Run! Runaway
0:000> !runaway User Mode Time Thread Time 4:242c 0 days 0:00:00.000 3:1978 0 days 0:00:00.000 2:2a60 0 days 0:00:00.000 1:2b74 0 days 0:00:00.000 0:26d4 0 days 0:00:00.000
Run. Time to see how long the process has been running
0:000> .timeDebug session time: Mon May 20 17:22:13.000 2013 (UTC + 8:00)System Uptime: 0 days 7:14:13.190Process Uptime: 0 days 0:00:11.000 Kernel time: 0 days 0:00:00.000 User time: 0 days 0:00:00.000
Run! Threads View statistics of all threads
0:000> !threadsThreadCount: 3UnstartedThread: 0BackgroundThread: 1PendingThread: 0DeadThread: 0Hosted Runtime: no Lock ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception 0 1 26d4 00000000004fe850 2a020 Preemptive 0000000002826698:0000000002827FD0 00000000004d2ab0 2 MTA 2 2 2a60 00000000005056a0 2b220 Preemptive 0000000000000000:0000000000000000 00000000004d2ab0 0 MTA (Finalizer) 4 3 242c 000000000052aca0 202b020 Preemptive 0000000002828010:0000000002829FD0 00000000004d2ab0 0 MTA
Run! Syncblk to check which threads have obtained the lock
0:000> !syncblkIndex SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 2 000000000052b978 3 1 00000000004fe850 26d4 0 0000000002822e88 ConsoleApplication1.Program-----------------------------Total 2CCW 0RCW 0ComClassFactory 0Free 0
Remarks
- If the interface is dead, you can directly find the UI thread (one for the stathread)
- A stack is divided into a local stack and a hosting stack. The thread number also includes a local thread number and a hosting thread number.