什么是"无法评估表,因为代码目前的方法是优化。"的意思吗?
-
02-07-2019 - |
题
我写了一些码有一个很大的递归,这需要相当多的时间来完成的。每当我"暂停"的运行要看看什么我会得到:
无法评估表,因为代码目前的方法是优化。
我觉得我明白这意味着什么。然而,什么我困惑的是,在我打步骤,代码不是"优化"了,我可以看看我的变量。这是怎么发生的?怎么可以代码翻之间来回行优化和非optimzed代码?
解决方案
调试器使用FuncEval允许您“查看”变量。 FuncEval要求在GarbageCollector安全点的托管代码中停止线程。手动“暂停” IDE中的运行会导致所有线程尽快停止。您的高递归代码将倾向于停在不安全的位置。因此,调试器无法计算表达式。
按F10将移至下一个Funceval Safe点并启用功能评估。
有关详细信息,请查看 FuncEval规则一>
其他提示
虽然Debug.Break()行位于callstack之上,但您无法评估表达式。那是因为该线路已经过优化。按F10移动到下一行 - 一行有效的代码 - 手表将起作用。
您可能尝试在发布模式而不是调试模式下调试应用程序,或者在编译设置中打开了优化。
当使用优化编译代码时,某些变量一旦在函数中不再使用就会被丢弃,这就是您获取该消息的原因。在禁用优化的调试模式下,您不应该收到该错误。
这让我抓狂。我试图附加的管理和机代码-不去。
这个工作对我来说我终于能够评估所有表现形式:
- 进入项目/特性
- 选择建立标签,并点击 高级...
- 确保"调试"的信息设定为"完全" (不pdb-only)
- 调试项目-瞧!
以下对我有用,谢谢@Vin。
我在使用VS 2015时遇到了这个问题。我的解决方案:配置已选中(Debug)。我通过取消选中项目属性下的 Optimize Code
属性来解决这个问题。
项目(右键单击)=>属性=> Build(tab)=>取消选中优化代码
查找带有多个参数的函数调用,并尝试减少该数字直到调试返回。
确保你没有那样的东西
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
汇编信息
中的
最可能的问题是您的调用堆栈已经过优化,因为您的方法签名太大了。
有同样的问题,但能够通过关闭调试器中的异常捕获来解决它。单击[Debug] [Exceptions]并将例外设置为“User-unhandled”。
通常情况下我会关闭此功能但偶尔会派上用场。我只需要记得在我完成时将其关闭。
我在使用VS 2010时出现此问题。我的解决方案配置已选中(调试)。我通过取消选中项目属性下的Optimize Code属性来解决这个问题。 项目(右键单击)=>属性=> Build(tab)=>取消选中优化代码
在我的情况下,我的解决方案中有2个项目,并且运行的项目不是启动项目。 当我将其更改为启动项目时,调试开始再次起作用。
希望它有所帮助。
评估:
在.NET中,“功能评估(funceval)”是调试对象在某处停止时CLR注入一些任意调用的能力。 Funceval负责调试器选择的线程以执行所请求的方法。一旦funceval完成,它就会触发一个调试事件。从技术上讲,CLR已经为调试器定义了发布funceval的方法。
CLR允许仅在那些处于GC安全点的线程(即线程不会阻塞GC时)和Funceval Safe(FESafe)点(即CLR实际上可以对funceval进行劫持的情况下)启动funceval。 。因此,CLR的可能场景,一个线程必须是:
-
在托管代码中停止(并且在GC安全点):这意味着我们无法在本机代码中执行funceval。由于本机代码不在CLR的控件之内,因此无法设置funceval。
-
在第一次机会或未处理的管理异常(以及在GC安全点)停止:即在异常时,尽可能地检查以确定异常发生的原因。 (例如:调试器可能会尝试评估并查看引发异常时的Message属性。)
醇>
总的来说,在托管代码中停止的常用方法包括在断点处停止,步骤,Debugger.Break调用,拦截异常或在线程启动时停止。这有助于评估方法和表达式。
可能的解决方案: 根据评估,如果线程不在FESafe和GCSafe点,CLR将无法劫持线程以启动funceval。通常,以下有助于确保funceval在预期时启动:
步骤1:
确保您没有尝试调试“发布”建立。发布已完全优化,因此将导致讨论中的错误。通过使用标准工具栏或配置管理器,您可以在Debug&释放。
步骤2:
如果仍然出现错误,可能会设置Debug选项进行优化。验证&取消选中“优化代码”项目“属性”:
下的属性右键单击Project 选择选项“属性” 转到“构建”标签 取消选中复选框“优化代码”
第3步:
如果仍然出现错误,则调试信息模式可能不正确。验证&设置为“完整”在“高级构建设置”:
右键单击Project 选择选项“属性” 转到“构建”标签 点击“高级”按键 设置“调试信息” as“完整”
步骤4:
如果您仍然遇到此问题,请尝试以下操作:
做一个“清洁” &安培;然后一个“重建”您的解决方案文件 调试时: 转到模块窗口(VS菜单 - >调试 - > Windows - >模块) 在已加载模块列表中查找程序集。 检查列出的已加载程序集的路径是否符合预期 检查文件的已修改时间戳以确认程序集实际已重建 检查加载的模块是否已优化
结论:
它不是错误,而是基于某些设置的信息,也是根据.NET运行时的工作原理设计的。
在我的情况下,我处于发布模式,我改为调试它全部工作
我有一个类似的问题,当我在调试模式下构建解决方案并在执行路径中替换了pdb文件时,它得到了解决。
我相信你所看到的是优化的结果 - 有时一个变量将被重用 - 特别是那些在堆栈上创建的变量。例如,假设您有一个使用两个(本地)整数的方法。第一个整数在方法的开头声明,并且仅用作循环的计数器。在循环完成后使用第二个整数,它存储稍后写入文件的计算结果。在这种情况下,优化器可以决定重用第一个整数,保存第二个整数所需的代码。当您尝试在早期查看第二个整数时,您会收到有关“无法计算表达式”的消息。虽然我无法解释确切的情况,但优化器可以稍后将第二个整数的值传输到单独的堆栈项中,从而使您能够从调试器访问该值。