2008-09-25 610 views
44

我写了一些有很多递归的代码,需要很长时间才能完成。每当我“暂停”运行来看看这是怎么回事,我得到:由于当前方法的代码进行了优化什么是“无法评估表达式,因为当前方法的代码已经优化。”意思?

无法计算表达式。

我想我明白这是什么意思。然而,让我感到困惑的是,在我迈开步伐之后,代码不再“优化”,我可以看看我的变量。这是如何发生的?代码如何在优化代码和非优化代码之间来回切换?

+0

您是否找到解决此问题的解决方法? – 2010-01-15 14:07:24

+2

我不相信所选的答案是有帮助的。当你有机会时,检查几个月后“没有人”留下的答案。这样做可以帮助那些希望解决你原来的问题的人。 – Catskul 2010-05-04 21:09:38

+3

我在发布模式下调试(脸红)。拉马尔的回答让我检查。 – mayu 2014-11-26 00:48:13

回答

26

调试器使用FuncEval允许您“查看”变量。 FuncEval要求线程在GarbageCollector安全点的托管代码中停止。手动“暂停”IDE中的运行会导致所有线程尽快停止。你的高度递归代码往往会在不安全的地方停下来。因此,调试器无法评估表达式。

按F10将移动到下一个Funceval安全点,并启用功能评估。

欲了解更多信息,请查阅rules of FuncEval

25

您可能试图在发布模式而不是调试模式下调试您的应用程序,或者您在编译设置中打开了优化。

当代码被优化编译时,某些变量在函数中不再使用时就会被丢弃,这就是为什么您会收到该消息。在优化禁用的调试模式下,您不应该得到该错误。

+1

不,我没有试图调试在发布模式下构建的应用程序。 “ – 2008-09-25 05:49:13

-1

我相信你所看到的是优化的结果 - 有时一个变量会被重用 - 特别是那些在堆栈上创建的变量。例如,假设你有一个使用两个(本地)整数的方法。第一个整数在方法开始时声明,并且仅用作循环的计数器。您的第二个整数在循环完成后使用,它存储稍后写入文件的计算结果。在这种情况下,优化器可能决定重用您的第一个整数,保存第二个整数所需的代码。当您尝试尽早查看第二个整数时,您会收到有关“无法评估表达式”的消息。虽然我无法解释确切的情况,但优化器可能会在稍后将第二个整数的值转换为单独的堆栈项,导致您可以从调试器访问该值。

44

虽然Debug.Break()行位于callstack之上,但无法评估表达式。这是因为该线路已经优化。按F10移动到下一行 - 有效的代码行 - 手表将工作。

1

有同样的问题,但能够通过关闭调试器中的异常陷阱来解决它。点击[Debug] [Exceptions]并将例外设置为“User-unhandled”。

通常情况下,我有这个问题,但偶尔会派上用场。我只需要记得在完成时关掉它。

2

寻找一个带有许多参数的函数调用,并尝试减少数量直到调试返回。

7

这让我疯狂。我尝试使用托管代码和本机代码进行连接 - 不行。

这为我工作,我终于能够评估所有的表达式:

  • 走进项目/属性
  • 选择Build选项卡并单击 高级...
  • 确保调试信息设置为“全” (不是pdb专用)
  • 调试您的项目 - 瞧!
1

我在使用VS 2010时遇到了这个问题。我的解决方案配置选择了(调试)。我通过取消选中项目属性下的优化代码属性来解决此问题。 项目(右键点击)=> Properties => Build(tab)=>取消选中优化代码

0

在我的情况中,我的解决方案中有2个项目,并且运行的不是启动项目。 当我将其更改为启动项目时,调试开始重新开始。

希望它可以帮助别人。

0

评估:

在.NET中,“功能评估(funceval)”是CLR的同时调试某处停止注入一些任意呼叫的能力。 Funceval负责调试器选择的线程来执行请求的方法。 funceval完成后,它会触发调试事件。从技术上讲,CLR已经定义了调试器发布funceval的方法。

CLR只允许在GC安全点(即线程不会阻止GC)和Funceval Safe(FESafe)点(即CLR实际上可以为funceval进行劫持)的线程上启动funceval。一起。因此,可能出现的情况为CLR,线程必须是:

  1. 停在托管代码(并在GC安全点):这意味着我们不能做本地代码funceval。由于本机代码不在CLR的控制范围之内,因此无法设置funceval。

  2. 在第一次机会或未处理的托管异常(以及GC安全点)时停止:即在例外时尽可能多地检查以确定发生异常的原因。 (如:调试器可能会尝试评估,看到出现的异常Message属性。)

总体而言,常见的方式停在托管代码包括断点,一步,Debugger.Break呼叫停止,拦截异常,或者在一个线程启动。这有助于评估方法和表达式。

可能的解决方案: 根据评估,如果线程不在FESafe和GCSafe点上,CLR将无法劫持线程来启动funceval。一般来说,以下有助于确保funceval启动时预计:

第1步:

确保您是不是要调试“释放”的构建。发布已完全优化,因此会导致讨论中的错误。通过使用标准工具栏或配置管理器,您可以在调试&版本之间切换。

第2步:

如果仍然出现错误,调试选项可能会进行优化设置。验证&取消选中“优化代码”项目下的财产“属性”:

右键单击该项目 选择选项“属性” 转到“生成”选项卡 取消选中复选框“优化代码”

步骤# 3:

如果仍然出现错误,则调试信息模式可能不正确。验证&将其设置为“完全”,“高级构建设置”下:

右键单击该项目 选择选项“属性” 转到“生成”选项卡 点击“高级”按钮 集“调试信息”作为“完整的”

第4步:

如果您仍然面临着问题,请尝试以下操作:

做一个‘干净’&再出‘您的解决方案的F重建’ ile 调试时: 进入模块窗口(VS菜单 - >调试 - > Windows - >模块) 在加载模块列表中找到您的程序集。 检查对加载的程序集列出的路径是你希望它是 检查文件的修改的时戳确认,大会实际上是重建 检查加载的模块是否被优化或者不

结论是什么:

这不是一个错误,而是基于某些设置和基于.NET运行时如何设计的信息。

0

在我的情况,我是在释放模式的人,我改变调试它的所有工作

5

下为我工作,谢谢@Vin。

我在使用VS 2015时遇到了这个问题。我的解决方案:配置选择了(调试)。我通过取消选中项目属性下的Optimize Code属性来解决此问题。

项目(右键)=>属性=>生成(标签)=>取消选中优化代码

2

确保你没有类似的东西

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

AssemblyInfo

0

我有一个类似的问题,当我在调试模式下构建解决方案并替换执行路径中的pdb文件时,它得到了解决。

相关问题