调试死锁问题
今天遇到了一個應用程序死鎖了,由于是在測試人員的環境中,所以生成了一個dump文件,生成dump文件的方法可以用任務管理器,在任務管理器的進程列表中點擊右鍵,選擇“Create Dump File”,就會為該進程生成一個mini dump文件。
由于是自己的程序,所以一般進程對應的pdb文件和源代碼文件都有。下面以visual studio 2010和windbg分別說明如何定位到死鎖代碼。
(1)windbg方法。
因為我們猜測該程序死鎖了,所以用windbg打開dump文件,同時設置符號路徑,執行步驟
第一步:執行命令!locks
結果如下:
0:000> !locks
CritSec +13a8e18 at 00000000013a8e18
WaiterWoken??????? No
LockCount????????? 9
RecursionCount???? 1
OwningThread?????? f34
EntryCount???????? 0
ContentionCount??? 9
*** Locked
Scanned 31 critical sections
請注意 Owning Thread f34和***Locked.表明線程f34在等待所。
第二步:執行~命令,結果如下:
0:000> ~
.? 0? Id: 1614.16b8 Suspend: 0 Teb: 00007ff7`b4cbd000 Unfrozen
?? 1? Id: 1614.ff0 Suspend: 0 Teb: 00007ff7`b4cb9000 Unfrozen
?? 2? Id: 1614.a94 Suspend: 0 Teb: 00007ff7`b4cb7000 Unfrozen
?? 3? Id: 1614.f34 Suspend: 0 Teb: 00007ff7`b4b8e000 Unfrozen
?? 4? Id: 1614.1370 Suspend: 0 Teb: 00007ff7`b4b8c000 Unfrozen
?? 5? Id: 1614.4ac Suspend: 0 Teb: 00007ff7`b4b8a000 Unfrozen
?? 6? Id: 1614.1054 Suspend: 0 Teb: 00007ff7`b4b88000 Unfrozen
?? 7? Id: 1614.76c Suspend: 0 Teb: 00007ff7`b4b86000 Unfrozen
?? 8? Id: 1614.b70 Suspend: 0 Teb: 00007ff7`b4b84000 Unfrozen
?? 9? Id: 1614.1ad0 Suspend: 0 Teb: 00007ff7`b4b80000 Unfrozen
? 10? Id: 1614.184c Suspend: 0 Teb: 00007ff7`b4cb5000 Unfrozen
? 11? Id: 1614.114c Suspend: 0 Teb: 00007ff7`b4cb3000 Unfrozen
? 12? Id: 1614.161c Suspend: 0 Teb: 00007ff7`b4b7e000 Unfrozen
? 13? Id: 1614.17b8 Suspend: 0 Teb: 00007ff7`b4cbb000 Unfrozen
? 14? Id: 1614.15c Suspend: 0 Teb: 00007ff7`b4b82000 Unfrozen
? 15? Id: 1614.1900 Suspend: 0 Teb: 00007ff7`b4b7c000 Unfrozen
? 16? Id: 1614.c6c Suspend: 0 Teb: 00007ff7`b4b7a000 Unfrozen
? 17? Id: 1614.17cc Suspend: 0 Teb: 00007ff7`b4b78000 Unfrozen
找到f34線程的編碼為3
第三步:執行命令 ~3 kb查看3號線程堆棧,結果如下:
0:000> ~3 kb
RetAddr?????????? : Args to Child?????????????????????????????????????????????????????????? : Call Site
00007ffa`ab1c1148 : 00000000`01551080 00000000`00010100 ffffffff`fffffffe 00000000`00000000 : ntdll!ZwWaitForSingleObject+0xa
00007ffa`a63c6ea0 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000344 : KERNELBASE!WaitForSingleObjectEx+0x94
果然在等待鎖。
這就找到了死鎖位置,但是往往并不是僅僅因為這里代碼的問題,而是還有另外一個地方在使用鎖不正確導致的。
2)用visual studio 2010
第一步:和windbg方法一樣,打開dump文件,配置符號路徑,通常還需要load系統庫的符號,因為默認沒有系統庫文件的調試符號。
第二步:vc中并沒有像windbg那樣的命令!locks來顯示鎖的情況,只能靠自己分析了。但是也提供了一個很不錯的方法,點擊“debug"菜單,選擇”窗口“子菜單,再選擇”parallel stacks“菜單,會顯示所有的線程及其堆棧,如同windbg的~* kb命令一樣,非常有用。如圖所示:
第三步:慢慢分析,看看哪些線程在等待鎖,和windbg一樣,也可以很快發現死鎖的位置。
總結
- 上一篇: 字符串编辑距离的计算方法
- 下一篇: Cluster 注册表操作方法