【发布时间】:2014-07-01 14:56:21
【问题描述】:
我对@987654321@ 的出现感到困惑。 很可能有可能(见答案)进行干净的复制,但总体思路如下:
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<> 调用它可以正常工作。
关于什么可能导致它或如何调试它的任何线索?
更新
遵循antiduh 的问题:在任何接近的地方都没有从构造函数调用虚拟方法。发生这种情况时的实际堆栈跟踪非常简单,只有两个静态方法和一个简单实例。
唯一的线索似乎是线程。在程序执行中(不在调用堆栈中)有Parallel.ForEach() 和Thread.Sleep() 在之前调用了这个。关于处理不当的线程(使用常规的托管类)如何导致 AVE 的任何线索?
更新
将其缩小为 VS 错误,请参阅我的答案。
【问题讨论】:
-
什么是最小版本的代码仍然可以证明问题?我会继续删除代码,直到 AV 停止发生,并希望这能提供一些线索。
-
碰巧,您是从子类的构造函数中调用任何这个吗?您是否正在调用可能不存在的虚拟方法,因为构造函数尚未完成?
-
@Ryan 删除引发阻止 AV 发生的单个方法调用
-
@antiduh 真是有趣的想法,我会调查和更新
-
不正确地使用锁定来保护非线程安全的对象可能会导致内部对象损坏可能导致 AV。 List 类是非线程安全的。
标签: c# .net multithreading access-violation