1. 程式人生 > >Windows下獲取Dump檔案以及程序下各執行緒呼叫棧的方法總結

Windows下獲取Dump檔案以及程序下各執行緒呼叫棧的方法總結

【除錯死鎖】
1、!syncblk,檢視哪些執行緒拿到了鎖
2、~67e!clrstack 跳到某個拿到鎖的執行緒看它正在幹什麼操作,遲遲不肯釋放鎖
3、!runaway 檢視這個佔有鎖的執行緒運行了多長時間。
4、~*e!clrstack檢視所有執行緒的託管堆疊,看看哪些是正在等待鎖的,比如hang在System.Threading.Monitor.Enter(System.Object) 
5、~136s選擇該執行緒,顯示如下
0:000> ~136s eax=00005763 ebx=08deeb5c ecx=03eff0d4 edx=5570ab69 esi=08deeb5c edi=7ffd6000 eip=7c95ed54 esp=08deeb10 ebp=08deebb8 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 ntdll!KiFastSystemCallRet: 7c95ed54 c3 ret
找到ecx暫存器的值,複製後ctrl+f,向上查詢,會找到!syncblk的地方,如下
0:000> !syncblk Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 1906 03ee4be4 5 1 03ee8f88 22c8 67 185e2ef0 System.Object 5390 052ca39c 3 1 05292b30 1dd4 49 1060d3ac System.Object 9372 0530702c 15 1 0012d3a8 1aa8 80 185e7704 System.Object 11428 03eff0d4 35 1 053b8fa8 169c 120 166acd98 System.Object 15278 0531c6b4 61 1 06bc1430 26d8 86 1a5bea88 System.Object
可以看到136執行緒等待的鎖被120號執行緒佔著不放(格式有點亂,湊合看),
6、有時候通過ecx暫存器找鎖不是很確定,可以用~* kb來把所有執行緒堆疊打出來,然後根據!syncblk出來的同步快的值去搜索大概有多少個執行緒在等那個鎖。因為同樣是等待鎖,可等的狀態不一樣,有的在Q裡,有的鎖已經升級,有的去嘗試去拿鎖了,所以不一定當時ecx暫存器指向那塊記憶體,具體如何找到某個正在等待鎖的執行緒等待的鎖的記憶體地址,以及它正等待的這個鎖被哪個執行緒拿著,我還沒琢磨出規律來,但一般情況下,如果有其它同步物件的話,更難查。.net裡用我上面說的幾步就能查出鎖的問題了。