|
|
|||||||||||||||||||||||||||||
|
Обработка Segmentation Fault в C++Источник: habrahabrru
Вводная C++ является "небезопасным" ("unmanaged") языком, поэтому программы могут "вылетать" - аварийно завершать работу без сохранения данных пользователя, сообщения об ошибке и т.п. - стоит только, например, залезть в не инициализированную память. Например: или Всем было бы лучше, если бы мы могли "отловить" падение программы - точно так же, как в java ловим исключения - и выполнить хоть что-то перед тем, как программа упадет (сохранить документ пользователя, вывести диалог с сообщением об ошибке и т.п.) Общего решения задача не имеет, так как C++ не имеет собственной модели обработки исключений, связанных с работой с памятью. Тем не менее, мы рассмотрим два способа, использующих особенности операционной системы, вызвавшей исключение. Способ 1: SEH Если Вы используете OS Windows в качестве целевой ОС и Visual C++ в качестве компилятора, то Вы можете использовать Structured Exception Handling - расширение языка С++ от Microsoft, позволяющее отлавливать любые исключения, происходящие в программе. Общий синтаксис обработки исключений выглядит следующим образом: __try Вот "работающий пример" - "скопируй и вставь в Visual Studio" int memento() // обработка Segfault void fall() // генерация segfault int main(int argc, char *argv[]) Мне лично не удалось заставить заработать __finally (поэтому я и написал __except с кодом проверки, который всегда работает), но это, возможно, кривизна моих рук. Данная методика, при всей ее привлекательности, имеет ряд минусов: Один компилятор. Одна ОС. Не "чистый С++". Если Вы хотите работать без средств MS - Вы не сможете использовать эту методику Минусов оказалось настолько много, что приходится искать второе решение. Способ 2: POSIX - сигналы Способ рассчитан на то, что в момент падения программа получает POSIX-сообщение SIGSEGV. Это безусловно так во всех UNIX-системах, но это фактически так (хотя никто не гарантировал, windows - не posix-совместима) и в windows тоже. Методика простая - мы должны написать обработчик сообщения SIGSEGV, в котором программа совершит "прощальные действия" и, наконец, упадет: после чего мы должны зарегистрировать этот обработчик: Вот готовый пример: int memento() int main(int argc, char *argv[]) В отличие от SEH, это работает всегда: решение "многопоточное" (вы можете уронить программу в любом потоке, обработчик запустится в любом случае) и "кроссплатформенное" - работает под любым компилятором, и под любой POSIX-совместимой ОС. Ссылки по теме
|
|