Ответ 1
Попробуйте выполнить
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
Это не гарантирует, что значение AccessViolationException
задается спецификацией CLI, но на каждой платформе я знаю
Мне нужно написать тест, который проверяет, что мой код может обрабатывать AccessViolationException (или любое другое исключение WIN32 Corrupted State Exception - CSE), которое возникает в небезопасном контексте, как правило, путем вызова сторонней библиотеки lib. Это должно быть сделано с помощью С# в .net 4.0.
Я нашел этот связанный вопрос Как обрабатывать AccessViolationException и эту статью http://dotnetslackers.com/articles/net/All-about-Corrupted-State-Exceptions-in-NET4.aspx, в котором объясняется, как поймать эти CSE и их предысторию.
Поэтому я хотел бы спровоцировать WIN32 CSE в тесте, чтобы обеспечить правильную обработку в моем приложении. Что-то вроде:
Некоторый пример для тестирования:
public class MyExceptionHandler
{
[HandleProcessCorruptedStateExceptions]
public void HandleCorruptedStateException()
{
try
{
//Force genuine unsafe AccessViolationException
//not just a throw new AccessViolationException
}
catch(Exception e)
{
//Log/cleanup/other
}
}
public void DoesNotHandleCorruptedStateException()
{
try
{
//Force genuine unsafe AccessViolationException
//not just a throw new AccessViolationException
}
catch (Exception e)
{
//Log/cleanup/other
}
}
}
Тест:
class MyTest
{
[Test]
public void ShouldVerifyThatAnAccessViolationExceptionIsHandledCorrectly()
{
var handler = new MyExceptionHandler();
Assert.DoesNotThrow(() => handler.HandleCorruptedStateException());
}
[Test]
public void ShouldVerifyThatAnAccessViolationExceptionIsNotHandledCorrectly()
{
var handler = new MyExceptionHandler();
Assert.Throws<AccessViolationException>(() => handler.DoesNotHandleCorruptedStateException());
}
}
Есть ли у кого-нибудь предложение о том, как достичь этого без большой работы (например, выписывать небезопасную библиотеку, которая вызывает это исключение).
С уважением
ОБНОВЛЕНО: Чтобы соответствовать моему окончательному решению, спасибо JaredPar.
public class MyExceptionHandler
{
[HandleProcessCorruptedStateExceptions]
public void HandleCorruptedStateException()
{
try
{
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
}
catch(Exception e)
{
//Log/cleanup/other
}
}
public void DoesNotHandleCorruptedStateException()
{
try
{
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
}
catch (Exception e)
{
//Log/cleanup/other
}
}
}
Совет: Чтобы проверить это вручную, используйте простое консольное приложение из командной строки:
class Program
{
static void Main(string[] args)
{
var handler = new MyExceptionHandler();
if (args.Length > 1)
{
handler.HandleCorruptedStateException();
}
else
{
handler.DoesNotHandleCorruptedStateException();
}
}
}
Попробуйте выполнить
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
Это не гарантирует, что значение AccessViolationException
задается спецификацией CLI, но на каждой платформе я знаю
int *p = 0xFF004324;
int q = *p;
Отредактировано небезопасное письмо. Чтение с этого адреса должно по-прежнему генерировать AccessViolationException, если случайно не находится в вашем адресном пространстве.