If the debugger hangs on you when debugging managed code (C#, VB, J#), try disabling “Allow property evaluation in variables windows“ (Tools/Options/Debugging/General).

Technical Details

In order for the debugger to display the value of a managed property, it has to execute that property in the debuggee, the one you are currently stopped in. This is a hugely scary & complex thing to do: your app is stopped, we hijack it, run the property, then put the app back where it was before. Hopefully. Most of the time this is reliable, as most properties are just thin wrappers over member variables. However, some properties do much more complicated things, and when things go awry, this debuggee function evaluation (which we call funceval) doesnt come back, so the debuggee is stuck. Meanwhile the debugger is stuck waiting for it to come back, and the IDE hangs. You then curse Microsoft a bunch.

What causes this to “go awry“? An infinite loop would be the easiest example. Another is an inter-thread call (as funcevals only run on the one thread, all other threads are suspended). Another is a property that takes too long, or has a nasty side-effect.

When bad things happen, the debugger does ask the CLR to Abort the funceval. However this often fails to works, especially if the “sticking“ is happening in native code (as the CLR has no power to stop native code).

This setting has no effect on native code debugging, though this same setting change can improve the stability of interop (aka mixed mode) debugging (native+managed).

Unfortunately it is difficult for users to tell if their debugger hang is caused by an errant property or some other bug. For internal users we can examine a minidump of the hung IDE and tell, and even tell the property that is at fault. This isnt feasible for external users though. If you still get hangs with the option disabled, firstly upgrade from 7.0 to 7.1 if you havent already. There were some important changes for improved reliability in the CLR and the debugger.

VS “Whidbey”

The “Whidbey” debugger is better at handling these situations as the CLR has a new method that we call, RudeAbort, but it still cannot help if native code is the real cause of the problem in the property. We also have more options to allow more granular control over when we funceval exactly, and to automatically stop doing funcevals once a method is needed to be aborted, and alerting the user to the problem. There is still no 100% guaranteed way for the debugger to safely funceval things, which is why you often hear the mantra in the halls here of “funceval is evil”.

MSFT disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights.