【问题标题】:Fatal Execution Engine Error in Managed C# code托管 C# 代码中的致命执行引擎错误
【发布时间】:2018-10-30 08:15:57
【问题描述】:

我在 C# 的托管代码中遇到了访问冲突异常和致命的执行引擎错误(似乎是相同的错误)。我已将其范围缩小到以下 sn-p。我错过了什么吗?我认为托管代码中不应出现此类异常。我在 .net 4.7 和 4.5 以及多台不同的计算机上都看到过它? 这是 .Net 中的一个已知问题吗?

    public static class FatalExecutionEngineBugExposer
{

    public static void Main(string[] args)
    {

        for (int i = 0; i < 500000; i++)
        {
            try
            {
                var testProblem = new TestProblem();
                testProblem.AddTrianglesExperiment();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.GetBaseException());
            }
        }
    }

    public class TestProblem
    {
        public struct Point
        {
            public double X, Y, Z;
        }

        public void AddTrianglesExperiment()
        {
            var points = new Point[28800];

            Parallel.ForEach(Partitioner.Create(0, points.Length),
                range =>
                {
                    // Create cache
                    var cache = new CubeRefCache();
                    cache.Entries = new CubeRefCacheEntry[20000];

                    // Add triangles
                    for (int i = range.Item1; i < range.Item2; i++)
                    {
                        ProcessTriangle(ref points[i].X, ref points[i].Y, ref points[i].Z, cache);  
                    }
                });
        }

        void ProcessTriangle(ref double pt1, ref double pt2, ref double pt3, CubeRefCache cache)
        {
            cache.Add(0, 0);
        }

        public struct CubeRefCacheEntry
        {
            public int Index;
            public int Item;
        }

        class CubeRefCache
        {
            internal CubeRefCacheEntry[] Entries;

            internal void Add(int index, int item)
            {
                Entries[0].Index = index;
                Entries[0].Item = item;
            }
        }
    }
}

这个 sn-p“通常”在一分钟内失败。

更新:它可能应该以 64 位运行。如果使用“Any CPU”编译,则重现问题需要更长的时间。

UPDATE2:我的用途:

usings

【问题讨论】:

  • 您的 ProcessTriangle 每次都访问相同的条目是有意的。请为分区器添加代码
  • "Partitioner" 是 .NET 框架的一部分,无需为此添加代码。
  • 如果此代码因致命的执行引擎异常而失败,那么在我看来,这就像 .NET 运行时中的某个错误。当然,代码是人为的,就像缓存从不添加任何东西,只是将所有内容存储在第一个元素中,但如果它重现崩溃,那就足够了。但是,我已经在 LINQPad 中运行了这段代码至少 5 分钟,它还没有崩溃,所以我想如果它在一分钟内可靠地崩溃,那么肯定还有其他事情发生。
  • 这是一个人为的例子并不重要。然而,当涉及到真正发现真正的问题(在运行时)时,可能会有一些不必要的部分和红鲱鱼,但这些都不重要。如果它是运行时中的错误,并且在我看来是这样(假设它确实崩溃,正如我所说的我无法重现它),那么它应该被修复或至少被放在优先级的错误列表中。 请不要抱怨所有使该代码有用或优雅的代码已被删除,这就是minimal reproducible example 的意思!
  • 可以在 x64 上以 1 分 40 秒的速度进行复制。事实上,如果我将public int Item;Entries[0].Item = item; 注释掉,它会立即或在几秒钟内崩溃。

标签: c# access-violation executionengineexception


【解决方案1】:

原始 Github 问题 (https://github.com/dotnet/corefx/issues/33157) 已作为 https://github.com/dotnet/coreclr/issues/20690 的副本关闭。显然,这是一个已在 .NET 4.8 中修复的已知问题。

【讨论】:

  • 该死,他们从 3 月 11 日就知道这个可怕的错误,但没有修复它。具体而言,这意味着如果您希望它在 64 位模式下运行,则不能编写具有超过 3 个参数的方法。 4 如果是静态的。 OP 可以通过省略 ref 并将 cache 变量作为第一个参数传递来解决它。传递一个点也是一种解决方法。
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 2010-09-27
  • 2010-10-16
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
相关资源
最近更新 更多