Восстановление из исключений
В нашем приложении (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