Можно ли использовать команду с многоточием для выявления всех ошибок, которые могут привести к сбою? Есть ли аномалии?
try
{
//some operation
}
catch(...)
{
}
Можно ли использовать команду с многоточием для выявления всех ошибок, которые могут привести к сбою? Есть ли аномалии?
try
{
//some operation
}
catch(...)
{
}
Нет, он будет ловить только исключения C ++, а не такие вещи, как segfault, SIGINT и т. Д.
Вам необходимо прочитать и понять разницу между исключениями C ++ и, если не хватает лучшего слова, «сигналами в стиле C» (такими как SIGINT).
Если код внутри блока try / catch каким-то образом разбился, программа все равно находится в невосстановимом состоянии. Вы не должны пытаться предотвратить сбой, лучшее, что может сделать программа, - это просто дать процессу сбой.
«Аномалия» заключается в том, что ваш код улавливает только исключения, а не ошибки. Даже если код безопасен в отношении исключений (что может быть не так, если вы пытаетесь обойти его ошибки с помощью блока try / catch), любая другая внутренняя ошибка может привести программу в безвозвратное состояние. Защитить программу от этого просто нет возможности.
Дополнение: прочтите эту статью в "Старом новом", чтобы получить дополнительную информацию.
catch
оператором throw;
, чтобы продолжить бросок.
- person Mooing Duck; 12.10.2011
std::cerr
в состоянии сбоя может перезаписать буфер потока RIAA или межпроцессную память, которая затем будет сброшена во время раскрутки стека. Значит ты прав. Сведите к минимуму нанесенный ущерб. Не используйте catch (...)
.
- person Mooing Duck; 12.10.2011
catch(...)
ловит SE (!), поэтому программа потенциально находится в очень плохом состоянии.
- person Vlad; 13.10.2011
Это обработчик Catch All.
Он перехватывает все исключения C ++, возникающие из блока try. Он не улавливает segfault и другие сигналы, которые вызывают сбой вашей программы.
При его использовании вам необходимо поместить этот обработчик в конец всех других конкретных обработчиков catch, иначе все ваши исключения будут перехвачены этим обработчиком.
Использование обработчика catch all - плохая идея, потому что он просто маскирует ваши проблемы и скрывает неспособность программы, перехватывая все (даже нераспознанные) исключения. Если вы столкнулись с такой ситуацией, вам лучше позволить программе аварийно завершить работу и создать аварийный дамп, который вы сможете проанализировать позже и устранить корень проблемы.
throw;
- person Mooing Duck; 12.10.2011
std::exception
в обработчике верхнего уровня.
- person Cat Plus Plus; 12.10.2011
catch(...)
шансы, что что-то пошло не так, довольно высоки. В частности, вполне разумны шансы, что куча находится в несогласованном состоянии или принята глобальная блокировка ввода-вывода.
- person Vlad; 13.10.2011
catch(...)
вызывается только для исключений C ++. Чтобы вызвать вызов, стек должен быть достаточно последовательным, чтобы можно было проследить обратную связь и найти обработчики catch. По пути разматывание стека будет (пытаться) уничтожить местных жителей. Обычно это связано с некоторыми delete
s, поэтому, если куча действительно повреждена, она, вероятно, выйдет в ОС до того, как будет достигнут обработчик. В этом обработчике шансы на то, что система ужасно повреждена, на самом деле довольно малы. В статье, которую вы связали, говорилось о SetUnhandledExceptionFilter - это совершенно другая ситуация.
- person Jerry Coffin; 13.10.2011
catch(...)
ловит SEH, который может быть брошен в довольно неприятные моменты. (Так что между catch(...)
и SetUnhandledExceptionFilter
нет такой большой разницы.) Здесь есть комментарий ТАК предполагая, что в Linux catch(...)
может поймать сигнал (если я правильно понял), но я не смог найти никаких упоминаний об этом в Интернете.
- person Vlad; 13.10.2011
/EHa
. Но наш архитектор в шляпе не надел. (Возможно, потому, что он был преобразован из какого-то старого кода.)
- person Vlad; 13.10.2011
Он ловит все, что бросается, не ограничивается исключениями. Он не обрабатывает такие вещи, как утверждения отладки Windows, системные сигналы, ошибки segfaults.
TEST(throw_int) {
try {
throw -1;
} catch (std::exception &e) {
std::cerr << "caught " << e.what() << std::endl;
} catch (...) {
std::cerr << "caught ..." << std::endl;
}
}
Однако использование целого числа не рекомендуется. Лучше скинуть то, что унаследовано от std::exception
.
Тем не менее, вы можете ожидать увидеть что-то подобное как последнюю попытку задокументировать неудачу. Некоторые приложения не обязательно должны быть очень надежными. Внутренние инструменты могут стоить дороже, чем они стоят, если вы постараетесь сделать их лучше, чем все вместе взломанное дерьмо.
int main(int argc, char ** argv) {
try {
// ...
} catch (std::exception &e) {
std::cerr << "error occured: " << e.what() << std::endl;
return 1;
}
return 0;
}