我对AccessViolationException
的出现感到困惑。这是非常可能的(见答案)有一个干净的再现,但这里有一般的想法:
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%可重现的,甚至在稍微重构代码之后,将方法调用移到别处,在它之前放置额外的代码等等 - 在所有情况下{I}仍然会抛出特定的方法调用。直接调用时不会输入该方法(未点击断点)。通过委托或AccessViolationException
调用它可以正常工作。
关于可能导致它的原因或如何调试它的任何线索?
更新
遵循antiduh的问题:在任何地方都没有从构造函数调用虚方法。发生这种情况时,实际的堆栈跟踪非常简单,只需要两个静态方法和一个简单的实例。
唯一的线索似乎是线程。在程序执行中(而不是在调用堆栈中)之前调用 Func<>
和Parallel.ForEach()
。关于错误处理线程(使用常规托管类)如何导致AVE的任何线索?
更新
将其缩小为VS错误,请参阅我的回答。
答案 0 :(得分:7)
这似乎是 VS bug 。看看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解决了这个问题。