今天我正在调试我的一些构建一些ExpressionTrees的代码,将它们编译成可调用的Delegates,然后在需要时调用它们。在执行此操作时,我遇到了FatalExecutionEngineError
单步执行代码:
起初我有点震惊,因为我不知道我的表情可能出现什么问题,他们看起来很好。然后我发现这只发生在以下情况:
Method A
是一个静态方法,它被调用并生成ExpressionTree,它可能再次包含Expression.Call()
到Method A
。因此,在为ExpressionTree编译Lambda之后,如果我在此方法中调用它,则生成的Delegate(让我们称之为Method B
)可能会导致递归...(Method A
- > {{1 }} - > [Generated]Method B
)。
...这在我的场景中是完全可能的。如上所述,我正在调试这段代码,所以我在Method A
中设置了一个断点。
常规代码第一次调用Method A
时,断点会照常播放。当调用Method A
时,断点会再次出现,但一切都还可以。
但是一旦我通过踩过最后一行而使用调试器离开第二个电话,Method B
就会出现。
如果我在没有调试的情况下运行代码,或者没有进入对FatalExecutionEngineError
的递归调用,或者如果我没有跨过该方法的最后一行,则问题不会发生并且我的表达式代码是按预期执行。
我无法确定这是VS-Debugger或.NET Framework中的错误,还是我做了一些非常可怕的错误,只有在调试相关行时才会出现错误。
这是一个非常简单的示例代码,您可以开箱即用。我正在使用Visual Studio 2013 Prof更新4和.NET 4.5.1。只需在Method A
中设置一个断点并尝试直到最后 - 如果可以的话;)
任何人都可以确认错误,或者我的表情格式不正确吗?
DoSomething()
答案 0 :(得分:6)
你的repro代码很棒,这可靠地炸弹。它对于32位代码的v4调试引擎非常具体,对于v2引擎或64位调试器引擎不会发生。旧的和新的v4引擎都有这个问题。
我调试调试器时看不到任何可识别的内容,失败的代码位于带有显式 throw 的mscorlib.dll中。没什么熟悉的,我看到一些名为ILTree
的非托管类的提示。不是Microsoft与我们共享的内容,它不存在于Reference Source,SSCLI20或CoreCLR源代码中。
这是微软需要担心的事情。通过connect.microsoft.com报告错误。这个SO问题的链接应该足以记录它。如果您不想花时间去做,请告诉我,我会照顾它。
与此同时,你确实有一个不错的解决方法,只需通过消除抖动强制让你的程序在64位模式下运行。单击项目+属性,构建选项卡,取消选中“首选32位”选项,并为平台目标选择AnyCPU。当您收到微软的回复时,请跟进。