Basically I have a c# server program (a console app not in IIS) which occasionally enters deadlock.
One thing that's strange is when I attach the debugger I see 3 threads waiting on a lock but no threads (using the threads window in visual studio) inside the lock! What's going on here .... I guess the visual studio debugger is lying.
But anyway .... what techniques or tools should I be using?
Thanks
I would start by sending trace output every time a thread is about to enter/leave a critical section as well as every time it successfully acquires a lock. Use the System.Diagnostics.Trace
class.
Then you should be able to determine from your trace output which thread actually has the lock.
Typical trace code:
Trace.WriteLine("Acquiring lock - foo");
lock (foo)
{
Trace.WriteLine("Acquired lock - foo");
// Do some stuff
Trace.WriteLine("Releasing lock - foo");
}
Trace.WriteLine("Released lock - foo");
Depending on the way your program is structured, this might not be useful unless you include thread information in the trace output, for example:
Trace.WriteLine(string.Format("Thread {0} - Acquiring lock - foo",
Thread.CurrentThread.ManagedThreadId));
Once you've figured out which thread has the lock, you can go into the debugger and see which lock it's waiting for, then use the same trace output to figure out who has the other lock. In most cases there will be two threads participating in a deadlock and this will let you find both of them.
There is always WinDbg, but the learning curve can be a bit daunting.
But see Brians excellent answer on this question: Detecting deadlocks in a C# application
You can also use WinDbg with the SOS.dll to find out where a deadlock resides. Have a look at this article. The SOS.dll command in question is !syncblk - it scans .NET threads looking for information about potential deadlocks.
EDIT: Just in case the article vanishes off the web, here is the internet archive link...
https://web.archive.org/web/20170208160911/http://dotnetdebug.net/2006/02/23/syncblk-in-sos-for-net-framework-20/
You probably have a race condition with your threads. One of your threads is not giving up a lock and it's not using it or allowing anyone else to use it. It also happens when a thread has the lock and is killed before giving it up. You might want to check out any of the programming solutions for deadlock, such as Sleeping Barber, Lamport's Bakery, Dekker's Algorithm, Peterson's Algorithm or Dining Philosophers.
I don't know how you're managing your threads, so I can't tell you which of the algorithms are the right solutions, but they are the most common solutions for concurrency and deadlock management inside of Operating Systems, so they should handle your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With