奇怪的访问冲突异常

Jac*_*goń 14 .net c# multithreading access-violation

我很困惑AccessViolationException.这是相当IM可能(请参阅回答)有一个干净的再现,但在这里不用的总体思路:

class MyClass 
{
  public List<SomeType> MyMethod(List<string> arg)
  {
     // BREAKPOINT here
     // Simple stuff here, nothing fancy, no external libs used
  }
}

delegate List<SomeType> MyDelegate(List<string> arg);

... 

var myObject = new MyClass();

Func<List<string>, List<SomeType>> myFunc = myObject.MyMethod;
MyDelegate myDelegate = myObject.MyMethod;

myFunc(null)            // works fine
myDelegate(null)        // works fine
myObject.MyMethod(null) // throws AccessViolationException
Run Code Online (Sandbox Code Playgroud)

奇怪的是我没有使用任何不安全的代码.我对任何地方(以及整个程序执行AFAIK中的任何地方)的外部库都没有任何依赖关系.

最奇怪的部分是这是100%可重复的,甚至在稍微重构代码之后,将方法调用移到别处,在它之前放置额外的代码等等 - 在所有情况下AccessViolationException仍然抛出特定的方法调用.直接调用时不会输入该方法(未点击断点).通过委托调用它或Func<>工作正常.

关于什么可能导致它或如何调试它的任何线索?

UPDATE

在antiduh的问题之后:在任何地方都没有从构造函数调用虚方法.发生这种情况时的实际堆栈跟踪非常简单,只需要两个静态方法和一个简单实例.

唯一的线索似乎是线程.在程序执行(而不是在调用堆栈中)之前Parallel.ForEach()之前都会Thread.Sleep()调用它.关于错误处理线程(使用常规托管类)如何导致AVE的任何线索?

UPDATE

把它缩小到一个VS bug,看看我的回答.

Jac*_*goń 7

这似乎是一个VS bug.看看这个完整的解决方案.代码很简单:

using System;
using System.Collections.Generic;

namespace Foo
{
    public class MyClass
    {
        public virtual object Foo(object o1, object o2, object o3, object o4)
        {
            return new object();
        }
    }

    public sealed class Program
    {
        public static void Main(string[] args)
        {
            var myClass = new MyClass();
            object x = new object();
            myClass.Foo(null, null, null, new object()); // put a breakpoint here and once it stops, step over (F10) - AccessViolationException should be thrown in VS
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我之前错过的重要事实是代码在正常运行时实际上工作正常.只有当该特定行在VS(F10)中被切换时,才会发生访问冲突,并且它实际上发生在VS宿主进程中(即使最终的堆栈帧是我的代码).可以继续执行罚款.

我在VS 2013,版本12.0.21005.1 REL上发生了这个问题.它也发生在我测试过的其他3台机器上.

UPDATE

安装.NET Framework 4.5.2解决了这个问题.