Восстановление из исключений

В нашем приложении (C++) мы загружаем сторонние библиотеки DLL, используя LoadLibrary. Иногда эти библиотеки DLL вызывают исключения, такие как "Место чтения нарушения доступа 0x00000000..".

Можно ли восстановиться после такого исключения, например, используя try & catch или какой-то другой механизм? в другом мире возможно ли создать "песочницу" в том же процессе, который выдерживает такие события?

Спасибо

6 ответов

Решение

Вы можете попробовать другой тип обработчика исключений:

__try
{
    // Code that might cause an access violation goes here. 

}
__except (EXCEPTION_EXECUTE_HANDLER)
{
    int code = _exception_code();

}

Остерегайтесь, однако, такие обработчики не могут использоваться в любой подпрограмме, где объектам C++ нужно раскручивать стек, поскольку компилятор предупредит вас (раздраженно).

Нет, это не так. DLL имеет неограниченный доступ к контексту процесса, который ее вызывает. Вам нужно запускать ненадежные библиотеки DLL в их собственном контексте процесса.

В Windows, с компилятором VisualStudio, может использоваться механизм SEH.

__try
{
  char* ptr = 0;
  char val = *ptr;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
  std::cout<<"AV"<<std::endl;
}

Используйте опцию / EHa.

Вы можете попробовать /EH флаг - http://msdn.microsoft.com/en-us/library/1deeycx5%28v=vs.80%29.aspx - в Visual Studio, но исключения нарушения прав доступа, скорее всего, означают, что вы делаете что-то очень неправильно. Я позволил бы программе аварийно завершить работу и попытался бы решить исключение, а не перехватывать его.

Люди, стоящие за Runtime-Compiled C++, используют функцию структурированной обработки исключений для своих процедур обработки сбоев DLL. Зайдите на их сайт или спросите их, хотите ли вы примеры кода.

Согласно MSDN, /EHa Параметр "Обработка исключений в C++ со структурированной обработкой исключений". Так что если вы используете msvc компилятор, вы можете попробовать это.

Это не возможно в C++, если, это невозможно, выдает кросс-модули исключений больше, в любом случае у вас будет повреждение памяти в вашем приложении, поэтому вы должны выяснить, что происходит в вашей DLL. Вы можете проверить причину, по которой вы не можете выбросить исключение из dll здесь: http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

Другие вопросы по тегам