奇怪的访问冲突异常 [英] Weird Access Violation Exception

查看:21
本文介绍了奇怪的访问冲突异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 AccessViolationException 的出现感到困惑.很可能有一个干净的复制品(见答案),但总体思路是这样的:

I'm puzzled with an occurance of AccessViolationException. It's quite impossible (see answer) to have a clean reproduction but here goes the general idea:

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

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

The weird part is I'm not using any unsafe code. I don't have any dependencies on external libraries anywhere close (and anywhere in the whole program execution AFAIK).

最奇怪的部分是这是 100% 可重现的,即使在稍微重构代码之后,将方法调用移到其他地方,在它之前放置额外的代码等等. - 在所有情况下 AccessViolationException 仍然被抛出特定的方法调用.直接调用时永远不会进入该方法(未命中断点).通过委托或 Func<> 调用它可以正常工作.

The weirdest part is this is 100% reproducable and even after refactoring the code slightly, moving the method invocation elsewhere, putting extra code before it etc. - in all cases AccessViolationException is still thrown on that particular method invocation. The method is never entered when invoked directly (breakpoint is not hit). Invoking it through delegate or Func<> works fine.

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

Any clues as to what could cause it or how to debug it?

更新

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

Following antiduh's question: There is no call to a virtual method from a constructor anywhere close. The actual stack trace when this happens is very simple, just two static methods and a simple instance one.

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

The only clue seems to be threading. There is Parallel.ForEach() and Thread.Sleep() invoked before this in program execution (not in call stack). Any clues as to how mishandled threading (with regular, managed classes) could cause AVE?

更新

将其缩小为 VS 错误,请参阅我的答案.

Narrowed it down to a VS bug, see my answer.

推荐答案

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

This seems to be a VS bug. Have a look at this full solution. Code is simple:

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
        }
    }
}

我之前错过的一个重要事实是,代码在正常运行时实际上可以正常工作.仅当在 VS (F10) 中跨过该特定行时,才会发生访问冲突,并且它实际上发生在 VS 托管进程中(即使最终堆栈帧是我的代码).可以继续正常执行.

The important fact I have missed before is that the code actually works fine when ran normally. Only when that particular line is being stepped over in VS (F10), the Access Violation occurs and it actually occurs in VS hosting process (even though the final stack frame is my code). It's possible to continue execution fine.

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

The issue happens for me on VS 2013, version 12.0.21005.1 REL. It also happens on 3 other machines I tested this on.

更新

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

这篇关于奇怪的访问冲突异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆