What does "Cannot evaluate expression because the code of the current method is optimized." mean?

Viewed 58855

I wrote some code with a lot of recursion, that takes quite a bit of time to complete. Whenever I "pause" the run to look at what's going on I get:

Cannot evaluate expression because the code of the current method is optimized.

I think I understand what that means. However, what puzzles me is that after I hit step, the code is not "optimized" anymore, and I can look at my variables. How does this happen? How can the code flip back and forth between optimized and non-optimzed code?

15 Answers

While the Debug.Break() line is on top of the callstack you can't eval expressions. That's because that line is optimized. Press F10 to move to the next line - a valid line of code - and the watch will work.

The Debugger uses FuncEval to allow you to "look at" variables. FuncEval requires threads to be stopped in managed code at a GarbageCollector safe point. Manually "pausing" the run in the IDE causes all threads to stop as soon as possible. Your highly recursive code will tend to stop at an unsafe point. Hence, the debugger is unable to evaluate expressions.

Pressing F10 will move to the next Funceval Safe point and will enable function evaluation.

For further information review the rules of FuncEval.

You are probably trying to debug your app in release mode instead of debug mode, or you have optimizations turned on in your compile settings.

When the code is compiled with optimizations, certain variables are thrown away once they are no longer used in the function, which is why you are getting that message. In debug mode with optimizations disabled, you shouldn't get that error.

Make sure you do not have something like that

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

in your AssemblyInfo

Had the same problem but was able to resolve it by turning off exception trapping in the debugger. Click [Debug][Exceptions] and set the exceptions to "User-unhandled".

Normally I have this off but it comes in handy occasionally. I just need to remember to turn it off when I'm done.

I had a similar issue and it got resolved when I build the solution in Debug Mode and replaced the pdb file in the execution path.

I believe that what you are seeing is a result of the optimisations - sometimes a variable will be reused - particularly those that are created on the stack. For example, suppose you have a method that uses two (local) integers. The first integer is declared at the start of the method, and is used solely as a counter for a loop. Your second integer is used after the loop has been completed, and it stores the result of a calculation that is later written out to file. In this case, the optimiser MAY decide to reuse your first integer, saving the code needed for the second integer. When you try to look at the second integer early on, you get the message that you are asking about "Cannot evaluate expression". Though I cannot explain the exact circumstances, it is possible for the optimiser to transfer the value of the second integer into a separate stack item later on, resulting in you then being able to access the value from the debugger.

Related