Исключение исключительного нарушения доступа
Я озадачен случаем 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% воспроизводимость и даже после небольшого пересмотра кода, перемещение вызова метода в другом месте, добавление дополнительного кода перед ним и т.д. - во всех случаях AccessViolationException все равно бросается на этот конкретный вызов метода. Метод никогда не вводится при непосредственном вызове (точка останова не попадает). Вызов его через делегат или Func < > работает нормально.
Любые подсказки относительно того, что может вызвать это или как его отладить?
UPDATE
Следующий вопрос antiduh: нет вызова виртуального метода от конструктора где-нибудь рядом. Фактическая трассировка стека при этом очень проста, всего два статических метода и простой экземпляр.
Единственный ключ, кажется, threading. Параллельно .ForEach() и Thread.Sleep() вызывается перед этим при выполнении программы (не в стеке вызовов). Любые подсказки относительно того, как неправильно обработанные потоки (с обычными, управляемыми классами) могут вызвать AVE?
UPDATE
Сузить его до ошибки VS, см. мой ответ.
Ответы
Ответ 1
Кажется, это ошибка VS. Посмотрите это полное решение. Код прост:
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 других машинах, на которых я тестировал это.
UPDATE
Установка .NET Framework 4.5.2 разрешает это.