是否有一种简单的方法来获取线程转储以查找线程死锁的原因?

时间:2017-05-04 14:18:40

标签: c# .net multithreading deadlock

我们在生产中有一个C#控制台应用程序,它具有间歇性的线程死锁。我试图通过将VS 2017附加到正在运行的进程来找到死锁,但我找不到任何方法来轻松找到死锁的原因。似乎没有任何窗口可以识别哪些线程拥有哪些锁。 (我尝试使用Memory窗口,但这根本不起作用。)

我也尝试过使用Dump文件,但发现很难理解它显示的内容。 (但这是在我知道我正在寻找僵局之前。)

我习惯于在Java中使用JStack,这是一个命令行实用程序,用于运行Java应用程序,它打印一个Thread转储,并识别死锁,并在每个StackTrace中显示一个Thread锁定监视器的点。

是否有一些与.NET相同的工具?

1 个答案:

答案 0 :(得分:3)

我使用WinDbg检查发生死锁时从进程中获取的完整userdump。确保您具有确切的二进制文件(DLL-s和PDB-s)以及转储文件。使用适当的WinDbg版本作为二进制文件(32位或64位)。

使用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.

相关问题