【问题标题】:Weird Access Violation Exception奇怪的访问冲突异常
【发布时间】:2014-07-01 14:56:21
【问题描述】:

我对@9​​87654321@ 的出现感到困惑。 很可能有可能(见答案)进行干净的复制,但总体思路如下:

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 的任何地方)都没有对外部库的任何依赖。

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

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

更新

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

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

更新

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

【问题讨论】:

  • 什么是最小版本的代码仍然可以证明问题?我会继续删除代码,直到 AV 停止发生,并希望这能提供一些线索。
  • 碰巧,您是从子类的构造函数中调用任何这个吗?您是否正在调用可能不存在的虚拟方法,因为构造函数尚未完成?
  • @Ryan 删除引发阻止 AV 发生的单个方法调用
  • @antiduh 真是有趣的想法,我会调查和更新
  • 不正确地使用锁定来保护非线程安全的对象可能会导致内部对象损坏可能导致 AV。 List 类是线程安全的。

标签: c# .net multithreading access-violation


【解决方案1】:

这似乎是一个 VS 错误。看看this full solution。代码很简单:

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 托管过程中(即使最终的堆栈帧是我的代码)。可以继续正常执行。

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

更新

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 2017-01-01
  • 2012-11-14
相关资源
最近更新 更多