Improving the reliability of the Visual Studio debugger on managed code (aka FuncEval is evil)

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.

Comments (6)
  1. Dan Szepesi says:

    Is this any more likely to happen when debugging ASP.NET code on a remote machine?

    I seem to to regularly get hangs when connecting to another machine and debug the aspnet_wp worker process on a Win2k machine.

    The debugging session hangs, the aspnet_wp worker process orphans, and I can never kill that orphaned process (even with kill.exe, task manager, etc.)

    Worse yet, my IDE refuses to hook up with the new aspnet_wp process, so I eventually have to shut down the IDE and start a new one.

    I have disabled the option – I guess I’ll see if I run into the problem again.

  2. Gil says:

    One of the problems I have with the auto evaluation of properties is assertions in the property definition that fire when automatically evaluated.

    I’d like to see an additional attribute that could be added to the property definition that would indicate the property shouldn’t be evaluated.

  3. Andy Pennell says:

    Great idea Scott, so great in fact that we already have it: try an attribute of DebuggerBrowsable.Never

Comments are closed.

Skip to main content