Действительно ли возможно поймать исключение нарушения прав доступа в.NET?

Есть ли что-либо, что я могу сделать для ловли AccessViolationException? Это бросается неуправляемым DLL, которым я не управляю.

29
задан John Saunders 22 July 2010 в 18:39
поделиться

2 ответа

Не следует. Нарушение прав доступа - серьезная проблема: это неожиданная попытка записи (или чтения) по недопустимому адресу памяти. Как уже пояснил Джон, неуправляемая DLL могла уже повредить память процесса до того, как возникло нарушение прав доступа. Это может иметь непредсказуемые последствия для любой части текущего процесса.

Самый безопасный вариант - по возможности проинформировать пользователя, а затем немедленно выйти.

Дополнительные сведения: Нарушение прав доступа - это исключение ОС (так называемое исключение SEH или структурированной обработки исключений ). Это исключение другого типа, чем управляемые исключения CLR из System.Exception . Вы редко увидите исключения SEH в чисто управляемом коде, но если они возникнут, напримерв неуправляемом коде среда CLR доставит его в управляемый код, где вы также сможете его перехватить 1 .

Однако перехват исключений SEH в большинстве случаев не является хорошей идеей. Дополнительные подробности объясняются в статье Обработка исключений поврежденного состояния в журнале MSDN, где приводится следующий текст, взятый из:

CLR всегда доставляла исключения SEH в управляемый код, используя те же механизмы, что и исключения, вызванные сама программа. Это не проблема, пока код не пытается обработать исключительные условия, которые он не может обработать разумным образом. Большинство программ не могут безопасно продолжить выполнение после нарушения прав доступа. К сожалению, модель обработки исключений CLR всегда побуждала пользователей отлавливать эти серьезные ошибки, позволяя программам перехватывать любое исключение на вершине иерархии System.Exception. Но это редко бывает правильным.

1 Так было до .NET 3.5. В .NET 4 поведение было изменено. Если вы по-прежнему хотите иметь возможность перехватывать такие исключения, вам нужно добавить legacyCorruptedStateExceptionsPolicy = true в app.config. Более подробная информация указана по ссылке выше.

29
ответ дан 28 November 2019 в 01:40
поделиться

вы можете обернуть вызов неуправляемой DLL блоком try-catch. Исключения AccessViolationExceptions могут быть пойманы нормально. Выполнение следующего кода показывает оба сообщения:

try
{
    throw new AccessViolationException();
}
catch (Exception e)
{
    MessageBox.Show(e.Message + e.StackTrace, e.Message, MessageBoxButtons.OK, MessageBoxIcons.Error);
}
MessageBox.Show("Still running..");

Edit: .NET 4 внесла изменение в поведение, теперь невозможно перехватить исключения поврежденного состояния, если вы специально не "попросите" среду выполнения сделать это.

0
ответ дан 28 November 2019 в 01:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: