2017-05-04 68 views
0

我們在生產中有一個C#控制檯應用程序,它具有間歇性線程死鎖。我試圖通過將VS 2017連接到正在運行的進程來發現死鎖,但我找不到任何方法輕易找到死鎖的原因。似乎沒有任何窗口標識哪些線程擁有哪些鎖。 (我嘗試使用內存窗口,但根本不起作用)。有沒有一種簡單的方法來進行線程轉儲以查找線程死鎖的原因?

我也嘗試過使用轉儲文件,但發現它很難理解它顯示的內容。 (但是,這是之前我知道我正在尋找一個死鎖。)

我習慣於在Java中使用JStack,一個命令行實用程序運行反對運行Java應用程序,它打印一個線程轉儲,並識別死鎖,和在每個StackTrace中顯示線程已鎖定顯示器的點。

是否有一些等效的.NET工具?

+1

,因爲它代表的問題是題外話的網站,因爲它是請求場外資源/工具。但是,如果您可以將代碼最小化爲[MCVE]併發布,我相信問題應該沒問題。通過這樣做,你也有可能找到它鎖定自己的原因。注意,log4net等日誌工具在配置正確時會打印線程標識,這可以幫助您在有足夠日誌記錄的情況下找到它所鎖定的原因。 – TheLethalCoder

+0

在.NET中你有沒有完全相同的信息?每個線程的調用棧...(如果你不想/不能附加VS,有庫,GUI和CL應用程序來執行它) –

+0

如果你附加到Visual Studio 2015的正在運行的進程,那麼你應該能夠'暫停'並打開一個名爲'Parallel Stacks'的東西(從主菜單中選擇Debug/Windows/Parallel Stacks) 我不知道在VS2017中可用,但我已經使用過這個功能幾次,這對我幫助很大。 – recineshto

回答

3

我會使用WinDbg來檢查死鎖發生時從進程中獲取的完整的userdump。確保你有確切的二進制文件(DLL-s和PDB-s)以及轉儲文件。爲您的二進制文件(32位或64位)使用適當的WinDbg版本。

使用File - >Open crash dump...命令打開您的轉儲,這將在WinDbg中打開一個「控制檯」窗口。您可以通過在底部輸入區域輸入命令來使用它。您可以通過將其記錄在Edit菜單中來保存所有WinDbg輸出。

您可以使用.loadby sos clr加載SOS擴展,然後使用!EEStack獲取所有調用堆棧。您可以嘗試使用-short參數來查看您是否在線程頂部顯示了相同的功能。

作爲@ dmitry-egorov在評論中提出的建議,您也可以使用SOSEX的!dlk

當你正在尋找可能導致僵局,尋找函數的函數 - 它們可能不是在堆棧的最頂端,但將接近 - 你的一些功能可能會試圖採取2不同順序的不同鎖和它們的死鎖。

Here's some documentation about how to use WinDbg.

+2

我會假設某人在網站上的聲譽應該比回答工具請求問題要好得多... – TheLethalCoder

+7

@TheLethalCoder我沒有看到這是一個「工具」問題 - 如果有人試圖在一個陌生的平臺上解決一個非常特殊的(和困難的)問題,這與要求「什麼是最好的免費圖書館......」是不一樣的。 (只有我的意見,你顯然不同意。)並非所有的問題都有很好的可重複的代碼片段。 – xxbbcc

+2

如何'有沒有一些等效的.NET工具?'不要求工具請求?是的,他們試圖排除故障,但沒有代碼,所以只需要一個工具來幫助他們。圍繞這個問題的情況並沒有改變這個問題。 – TheLethalCoder

相關問題