C#表达式 - FatalExecutionEngineError

Pue*_*tis 9 c# debugging expression expression-trees visual-studio-2013

今天我正在调试我的一些构建一些ExpressionTrees的代码,将它们编译成可调用的Delegates,然后在需要时调用它们.在这样做时,我遇到了FatalExecutionEngineError代码的踩踏:

FatalExecutionEngineError

起初我有点震惊,因为我不知道我的表达式可能出现什么问题,他们看起来很好.然后我发现这只发生在以下情况:

  • Method A是一个静态方法,它被调用并生成ExpressionTree,它可能包含一个Expression.Call()to Method A.因此,在为ExpressionTree编译Lambda之后,Method B如果我在此方法中调用它,则生成的Delegate(让我们调用它)可能会导致递归...(Method A- > [Generated]Method B- > Method A).

  • ......这在我的场景中是完全可能的.如上所述,我正在调试这段代码,所以我设置了一个断点Method A.

  • 第一次Method A由常规代码调用,断点像往常一样.当Method B调用时,断点会再次出现,但一切都还可以.

  • 但是一旦我通过踩到最后一行而与调试器进行第二次调用,FatalExecutionEngineError就会发生这种情况.

如果我在没有调试的情况下运行代码,或者不执行递归调用Method A,或者如果我不跳过方法的最后一行,则问题不会发生,并且我的表达式代码按预期执行.

我无法确定这是VS-Debugger或.NET Framework中的错误,还是我做了一些非常可怕的错误,只有在调试相关行时才会出现错误.

这是一个非常简单的示例代码,您可以开箱即用.我正在使用Visual Studio 2013 Prof更新4和.NET 4.5.1.只需设置断点DoSomething()并尝试直到最后 - 如果可以的话;)

任何人都可以确认一个错误,或者我的表情是不正确的吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ExpressionProblem
{
    public class MainClass
    {
        public static void DoSomething(bool stop)
        {
            var method = typeof(MainClass).GetMethod(
                "DoSomething",
                BindingFlags.Public | BindingFlags.Static,
                Type.DefaultBinder,
                new Type[] { typeof(bool) },
                null);

            var expParam = Expression.Parameter(typeof(bool), "stop");
            var expCall = Expression.Call(null, method, expParam);
            var lambda = Expression.Lambda(expCall, expParam);
            var @delegate = lambda.Compile();
            if(!stop)
            {
                @delegate.DynamicInvoke(true);
            }
        }

        public static void Main(string[] args)
        {
            DoSomething(false);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 6

你的repro代码很棒,这种炸弹可靠.它对于32位代码的v4调试引擎非常具体,对于v2引擎或64位调试器引擎不会发生.旧的和新的v4引擎都有这个问题.

我调试调试器时没有看到任何可识别的东西,失败的代码位于带有显式抛出的 mscorlib.dll中.没什么熟悉的,我看到一些名为的非托管类的提示ILTree.Microsoft不与我们共享,它不存在于Reference Source,SSCLI20或CoreCLR源代码中.

这是微软需要担心的事情.通过connect.microsoft.com报告错误.这个SO问题的链接应该足以记录它.如果您不想花时间去做,请告诉我,我会照顾它.

同时你有一个不错的解决方法继续前进,只需通过消除抖动强制让你的程序在64位模式下运行.单击项目+属性,构建选项卡,取消选中"首选32位"选项,并为平台目标选择AnyCPU.当您收到Microsoft的回复时,请跟进.

  • 非常感谢汉斯.每次我在问题发生前都傻眼了,你突然收到了这样详细的分析:)我已经在这里提交了错误报告:https://connect.microsoft.com/VisualStudio/feedback/details/1148770 (4认同)