創建死鎖程序
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");
}
}
}
}
運行程序后(不要點擊鍵盤)創建.dump文件
使用WinDbg進行分析
執行~*e!clrstack查看所有持有和等待鎖的線程(的下一條要執行的代碼)
0:000> ~*e!clrstack
OS Thread Id: 0x26d4 (0)
Child SP IP Call Site
000000000045ea38 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 in
the process
Failed to start stack walk: 80070057
OS Thread Id: 0x2a60 (2)
Child SP IP Call Site
000000001af8f8c8 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 in
the process
Failed to start stack walk: 80070057
OS Thread Id: 0x242c (4)
Child SP IP Call Site
000000001ba6e9d8 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]
執行!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
執行.time看進程運行了多長時間
0:000> .time
Debug session time: Mon May 20 17:22:13.000 2013 (UTC + 8:00)
System Uptime: 0 days 7:14:13.190
Process Uptime: 0 days 0:00:11.000
Kernel time: 0 days 0:00:00.000
User time: 0 days 0:00:00.000
執行!threads看所有的線程統計情況
0:000> !threads
ThreadCount: 3
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 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
可看到線程0有兩個鎖
執行!syncblk查看哪些線程拿到了鎖
0:000> !syncblk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
2 000000000052b978 3 1 00000000004fe850 26d4 0 0000000002822e88 ConsoleApplication1.Program
-----------------------------
Total 2
CCW 0
RCW 0
ComClassFactory 0
Free 0
可看到線程“00000000004fe850?”拿到了鎖,再通過!threads命令得到其線程邏輯號為0,即可切換至該線程,并通過!clrstack打印出其運行堆棧。
備注
- ? 若表現為界面死掉,就直接找UI線程(STA線程就一個)
- ? 堆棧分為本地堆棧與托管堆棧,線程號也有本地線程號與托管線程號
- ? 可使用!dso (DumpStackObjects)查看當前堆棧的所有對象
- ? 可使用?!analyze -v 分析掛掉線程的詳細情形,錯誤原因
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

