2017-05-04 69 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

相关问题