开发者

How do I debug a deadlock when only one thread shows up in Visual Studio?

My application is blocking indefinitely on a call to lock ( obj ), but there are no other threads in the threads window that have any code to browse at all. Isn't it kind of necessary for there to be another thread involved? Why isn't it showing up, and what could be the cause of it not showing up?

Update: I think I figured out what was causing it. I had this sort of hackish block whereby I would Wait() on a ManualResetEvent inside two locks. The problem was I needed to release those locks before Waiting so other threads could use them, so I was doing something like this:

lock ( one ) {
    lock ( two ) {
        ...
        Monitor.Exit( two );
        Monitor.Exit( one );
        syncEvent.Wait();
        Monitor.Enter( one );
        Monitor.Enter( two );
    }
}

What I wasn't counting on is that Monitor.Exit() really only decrements an internal recursion counter, and it wa开发者_高级运维s possible the method was being called from a block that was already synchronized; thus the lock was not actually being released.

I guess it was a bad idea to begin with. I've since just moved the call to Wait() outside of the locked blocks and it seems to be working fine now.

Thanks for the insight.

Although, now that I think about it, if the method is being called from code synchronized on one of the locks, it will still not be released when the call to Wait occurs. Therefore I'll have to be careful never to call this from a synchronized block, I guess.


there are no other threads in the threads window that have any code to browse at all

I assure you that those other threads are running code. Whether you have the source code on your machine or not doesn't matter to those threads.

Isn't it kind of necessary for there to be another thread involved?

Yes.

Why isn't it showing up, and what could be the cause of it not showing up?

Perhaps the thread that took out a lock has gone to sleep. It's rude to take a lock and then sleep without unlocking it, but certainly possible. Or perhaps one of those threads that is running code that you don't have the source code to took out a lock. For example, suppose the finalizer thread took out a lock while finalizing an object, and then the finalizer thread finished its current batch of work. Again, it is rude and stupid to lock an object during finalization and then not unlock it, but it is certainly possible.

There are a million possibilities; you haven't given us nearly enough information to do anything more than guess randomly. My advice: build a small repro that clearly demonstrates the problem. In doing so you'll either figure out what the problem is yourself, or you'll have something concrete that we can discuss rather than simply making guesses in advance of facts.


A good way to debug this is to run your program through the Concurrency Profiler in Visual Studio 2010. (This is only available in higher-end SKUs, however.) It includes many tools for highlighting and investigating deadlocks, and tends to work better in many scenarios than the debugger.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜