Обработка исключений процессора в C ++ - PullRequest
7 голосов
/ 25 января 2011

существует ли кроссплатформенный способ обработки исключений процессора, таких как ошибки сегментации или деление на ноль?Допустим, мне нужно вызывать некоторые потенциально небезопасные функции (например, из файла плагина), которые могут вызвать ошибку segfault, или некоторые другие проблемы, которые я не могу проверить перед выполнением.Я знаю, что стандартная библиотека C имеет функции обработки сигналов, но я не знаю, как их использовать для решения проблемы, чтобы избежать завершения программы (я думаю, я не могу просто перейти к месту до выполнения проблемных функцийили я могу?)Под окнами я мог использовать обработчики исключений SEH, но я не могу сделать это под Linux или любой другой ОС.Как насчет использования моего собственного обработчика исключений для решения этих проблем, насколько он отличается в Windows / Linux?Возможно ли это (через ассемблер - скажем, только на платформе x86)?

Я спрашиваю в основном из любопытства, я не пытаюсь решить существующую проблему (пока).Спасибо

Ответы [ 6 ]

5 голосов
/ 25 января 2011

libsigsegv - это кроссплатформенная библиотека для обработки ошибок сегментации и переполнения стека.Тем не менее, в подавляющем большинстве случаев, когда вы обнаруживаете ошибку сегментации, правильное решение - как можно быстрее прекратить выполнение, а не пытаться восстанавливаться после него.Segfault обычно указывает на ошибку или поврежденную память, и после того, как вы испортили память, практически невозможно восстановить ее.

2 голосов
/ 25 января 2011

Не думаю, что существует настоящее кроссплатформенное решение.

под окнами вы можете использовать _set_se_translator для перевода исключений SEH в исключения C ++.

См. Следующую статью Уловки обработки исключений C ++ для Linux , как сделать то же самое в Linux

2 голосов
/ 25 января 2011

Это не рассматривается в стандарте C ++, однако обычные настольные ОС предоставляют средства для этого. В Windows есть Структурная обработка исключений (SEH), для которой доступны соответствующие расширения компилятора, а POSIX обеспечивает обработку сигналов.

Как правило, я бы сказал, что вы не должны отлавливать исключения процессора - они возникают только в том случае, если ваша программа содержит ошибки и в этот момент пришло время отключить отладчик, а не продолжать.

Вы не можете использовать тот же подход - даже в ассемблере. Эти возможности предоставляются ОС - когда процессор выдает исключение, он обращается к ОС, чтобы решить, что с этим делать, а не в пользовательском режиме. Не только это, но я бы сказал, что SEH и обработка сигналов достаточно легко различаются, чтобы оправдать принципиально разные подходы при их использовании в коде, поэтому простой #ifdef не сократит его.

setjmp и longjmp могут работать только для «сигналов», генерируемых кодом пользовательского режима, но не уровнем ОС.

2 голосов
/ 25 января 2011

Проблема в том, что в случае сбоя в работе плагина вы не можете гарантировать, в каком состоянии находится ваша основная программа. Даже если бы вы могли поймать SIGSEGV (что, я полагаю, вы можете), у вас не будет хорошего способа восстановления в вашем приложении.

Что вам нужно сделать, это запустить плагин в fork редактируемом процессе, чтобы в случае его сбоя ваша основная программа тоже не удалялась. Вы можете общаться между процессами с помощью канала, например.

1 голос
/ 25 января 2011

Нет, стандартного способа нет. В C ++ такие «исключения процессора» являются проявлениями неопределенного поведения, то есть стандарт C ++ не определяет ничего об их поведении или о том, что происходит потом. Даже понятие «сегфо» не существует в стандарте C ++. Разыменование указателя NULL может привести к возгоранию вашего компьютера, и, очевидно, в этой точке осталось немного.

C тоже не решил: SIGSEGV не является стандартным сигналом C; это расширение POSIX. Например, в Windows нет SIGSEGV.

0 голосов
/ 25 января 2011

Обработчики сигналов могут зафиксировать выполнение программы до некоторой точки; что конкретно разрешено, задокументировано в справочной странице signal (7) .

Существуют реализации, которые будут

  • возврат к ошибочной инструкции от обработчиков SIGSEGV (это позволяет изменить карту памяти и возврат) и

  • перейти к инструкции после сбоя для SIGFPE (поэтому вашему обработчику сигнала необходимо найти инструкцию и предоставить результат)

Обратите внимание, что в лучшем случае это определяется реализацией. Руководство говорит вам не полагаться ни на что из этого. Вы были предупреждены. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...