检测 C# 应用程序中的死锁
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/508398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting deadlocks in a C# application
提问by Jon Tackabury
Possible Duplicate:
C#/.NET analysis tool to find race conditions/deadlocks
可能的重复:
C#/.NET 分析工具来查找竞争条件/死锁
I am debugging an application that I suspect is getting deadlocked and hanging. However, this only occurs every few days, and it never happens on my computer so I can't hook a debugger up to it. Are there any utilities or methods I can use to query the running application and find out what methods/locks/whatever it is deadlocked on?
我正在调试一个应用程序,我怀疑它会陷入僵局并挂起。但是,这只会每隔几天发生一次,而且它从未在我的计算机上发生过,因此我无法将调试器连接到它。我可以使用任何实用程序或方法来查询正在运行的应用程序并找出哪些方法/锁/无论它死锁了吗?
Update:Typically the application is running at a customer location and I don't have access to the machine, and I'm not entirely comfortable asking them to install tons of software.
更新:通常应用程序在客户位置运行,我无法访问机器,而且我不太愿意要求他们安装大量软件。
采纳答案by Frederik Gheysels
Instead of using the regular lock
& Monitor.Enter
approach to lock some data, you can also use a 'TimedLock' structure.
This TimedLock throws an exception if the lock couldn't be acquired in a timely fashion, and it can also give you a warning if you have some locks that you didn't release.
除了使用常规lock
&Monitor.Enter
方法来锁定某些数据,您还可以使用“TimedLock”结构。如果无法及时获取锁,此 TimedLock 将引发异常,如果您有一些未释放的锁,它也会向您发出警告。
Thisarticle by Ian Griffiths could maybe help.
Ian Griffiths 的这篇文章可能会有所帮助。
回答by ChrisW
The end of http://blogs.technet.com/askperf/archive/2007/06/15/capturing-application-crash-dumps.aspxsays that on Vista at least you can get a crash dump of a running process using Task Manager.
http://blogs.technet.com/askperf/archive/2007/06/15/capturing-application-crash-dumps.aspx的结尾说,至少在 Vista 上,您可以使用 Task 获得正在运行的进程的故障转储经理。
回答by Szymon Rozga
This is a very interesting problem and a pain because it only happens every few days. I found this article on CodeProject. It might be a start for you.
这是一个非常有趣的问题和痛苦,因为它每隔几天就会发生一次。我在 CodeProject 上找到了这篇文章。这对你来说可能是一个开始。
An old school approach is to log a ton of messages and use logfiles to try to detect when it occurs. :)
一个老派的方法是记录大量消息并使用日志文件来尝试检测它何时发生。:)
回答by mandel
You actually have a very interesting problem over there. There are several thing you can do:
你实际上有一个非常有趣的问题。你可以做几件事:
Use a good logger: One of the way to reproduce a multi thread error is to have a logger that will print the actions taken and the thread that performed them, that way you can find a trace the guides you to the error. This is a fairly easy solution if you can add the logger.
使用一个好的记录器:重现多线程错误的一种方法是使用一个记录器来打印所采取的操作和执行这些操作的线程,这样您就可以找到引导您找到错误的跟踪。如果您可以添加记录器,这是一个相当简单的解决方案。
Use FSP: Define your multi threaded system using FSP. This way you will be able to create a finite state machine of the process which you can walk through to find the error. This solution is a more mathematical solution.
使用 FSP:使用 FSP 定义您的多线程系统。通过这种方式,您将能够创建过程的有限状态机,您可以通过它来查找错误。这个解决方案是一个更数学化的解决方案。
The two solution/procedures I give you are exactly the main differences of approaching multi threaded development between some British universitis and the Amercian ones. In the U.K. professors are more kind to try and proof their system has no errors using FSP before they program it, and the Americans prefer to test to proof they work correctly, is a matter of taste.
我给你的两个解决方案/程序正是一些英国大学和美国大学之间接近多线程开发的主要区别。在英国,教授们在编程之前更愿意尝试使用 FSP 来证明他们的系统没有错误,而美国人更喜欢测试以证明他们的工作正常,这是一个品味问题。
I really recommend to read this book: Jeff Magee and Jeff Kramer: Concurrency: State Models and Java Programs, Wiley, 1999
我真的推荐阅读这本书:Jeff Magee 和 Jeff Kramer:并发:状态模型和 Java 程序,Wiley,1999
回答by Brian Rasmussen
You can use WinDbgto inspect the threads in the application. Here's a brief plan of what you could do.
您可以使用WinDbg检查应用程序中的线程。这是您可以做什么的简要计划。
- When the application hangs, copy the WinDbg files to the machine.
- Either attach WinDbg to the process or use ADPlus to get a hang dump of the process. If you choose ADPlus, you then load the dump in WinDbg.
- From WinDbg you load sos.dll, so you can inspect managed code.
- The
!threads
command will show you all threads in the application and the!clrstack
command, will show you what they are doing. Use~e!clrstack
to dump the call stack of all threads. Look for calls to Wait methods as they indicate locking. - The
!syncblk
command will give you information of what threads are holding the different locks. - To find out what lock a given thread is trying to acquire, switch to the thread and inspect stack objects (
!dso
). From here you should be able to find the lock the thread is trying to acquire.
- 当应用程序挂起时,将 WinDbg 文件复制到机器上。
- 将 WinDbg 附加到进程或使用 ADPlus 获取进程的挂起转储。如果选择 ADPlus,则将转储加载到 WinDbg 中。
- 从 WinDbg 加载 sos.dll,以便您可以检查托管代码。
- 该
!threads
命令将向您显示应用程序中的所有线程,而该!clrstack
命令将向您显示它们在做什么。使用~e!clrstack
转储全部线程的调用堆栈。查找对 Wait 方法的调用,因为它们指示锁定。 - 该
!syncblk
命令将为您提供有关哪些线程持有不同锁的信息。 - 要找出给定线程尝试获取的锁,请切换到该线程并检查堆栈对象 (
!dso
)。从这里您应该能够找到线程试图获取的锁。
Clarification: WinDbg doesn't require a regular install. Just copy the files. Also, if you take the hang dump, you can continue debugging on another machine if so desired.
说明:WinDbg 不需要定期安装。只需复制文件。此外,如果您进行挂起转储,您可以根据需要在另一台机器上继续调试。
Addition: Sosexhas the !dlk
command that automatically identifies deadlocks in many situations. It doesn't work all the time, but when it does, it does all the work for you, so that should be your first choice.
补充:Sosex有!dlk
在很多情况下自动识别死锁的命令。它并非一直有效,但当它有效时,它会为您完成所有工作,因此这应该是您的首选。
回答by Tim Jarvis
In addition to the answers here, another thing that you would find useful with thread programming in general is to make sure your dev box is a multiprocessor machine, deadlocks in particular are (usually) much more reliably reproduced.
除了这里的答案之外,您会发现对线程编程有用的另一件事是确保您的开发箱是多处理器机器,尤其是死锁(通常)更可靠地重现。
回答by naasking
Timeouts in concurrent programming is a horrible idea. This leads to non-determinism and thus behaviour that can't be reproduced. Try using a deadlock detection tool like CHESS. Better yet, minimize the number of locks used with lock-free algorithms, or eschew locks entirely and partition your program into single-threaded compartments and use queues to pass data between compartments (better known as message-passing/actor concurrency).
并发编程中的超时是一个可怕的想法。这会导致不确定性,从而导致无法复制的行为。尝试使用像CHESS这样的死锁检测工具。更好的是,尽量减少与无锁算法一起使用的锁的数量,或者完全避免使用锁并将您的程序划分为单线程隔间,并使用队列在隔间之间传递数据(更好地称为消息传递/actor 并发)。