2008-11-25 23 views
2

我有一個由於死鎖而掛起的.Net進程的轉儲(gui線程不再響應,而且我的日誌顯示某些線程已停止響應)。我拍了一張快照,現在正在用windbg瀏覽它,所有線程欄正在等待最後一個。看看這個線程的stacktrace!clrstack -p我可以看到它試圖在ReaderWriterLock上獲得寫入如何在windbg中找到我的ReaderWriterLock的鎖持有者(讀者)

如何判斷哪個其他線程持有該鎖,以便我可以開始瞭解死鎖是如何發生的?

感謝

[編輯]顯然有一個命令!rwlocks在.Net1.1 sos.dll來解決這個問題,但它是不存在的.Net2.0版本。狩獵繼續

回答

0

到目前爲止,最好的方法是查看所有線程堆棧的!dso,並查看哪些引用了鎖。之後的快速檢查讓我們追蹤哪些線程持有鎖。真的不是一個漂亮的或快速的方式,雖然...

1

我不是很確定,但你可以使用!SyncBlk查看同步塊對象,如果你調用它沒有任何參數我想你應該看到同步塊是由一個擁有的同步塊線。

如果您有一個同步塊死鎖,則可能需要擴展名SOSEX。該擴展提供了命令!dlk,該命令顯示哪些線程正在等待哪些鎖。這隻適用於同步塊,但其他同步對象上的死鎖不會被檢測到,如果你正在使用lock()(Monitor.Enter),這對你來說應該不是問題。

+0

我們正在使用內置的ReaderWriterLocks,它不會出現在!dlk – Oskar 2008-11-26 07:15:26

0

的一種方法,將提供可追溯性來包裝你的鎖到一個IDisposable接口並替換:

鎖(mylock){...}

使用

(新DisposeableLock()){...}

您可以登錄構造和的Dispose()方法,要麼到控制檯,或log4net的,或一些其他機制。這將允許您查看什麼是鎖定以及阻止什麼。

+0

我們的應用程序中有很多鎖,因此每個線程的兩行記錄會非常快速地累加起來。這個問題在10個用戶中似乎每兩個星期只發生一次,並且在開發環境中從未發生過,所以這是一個相當昂貴的方法。但是,如果沒有其他方法可行...... – Oskar 2008-11-27 08:44:53

+0

IDisposable鎖定可能會降低性能,因爲每個「DisposableLock」必須經過GC定型輪次,然後是GC的實際收集循環=有時會導致失去效用,內存異常,因爲分配內存比它到達GC隊列更快。 – 2008-12-09 03:06:47

1

嘗試sosex和!DLK

+0

!dlk只有在你有同步塊(如鎖(myObject。SyncRoot){}或顯示器),而不是ReaderWriterLocks – Oskar 2008-12-15 09:29:11