Микропроцессоры имеют ловушки для различных состояний неисправности.Это синхронные прерывания, которые позволяют работающей ОС / программному обеспечению предпринимать соответствующие действия в случае ошибки.Перехватывает поток программы прерывания и устанавливает регистровые биты для индикации неисправности.Точки останова отладчика также реализуются с использованием прерываний.
В типичной вычислительной среде операционная система заботится о прерываниях ЦП, запускаемых пользовательскими процессами.Давайте рассмотрим, что происходит, когда я запускаю следующую программу:
int main(void)
{
volatile int a = 1, b = 0;
a = a % b; /* div by zero */
return 0;
}
Отображалось сообщение об ошибке, и мой ящик все еще работает, как будто ничего не произошло.Подход моей операционной системы к обработке сбоев в этом случае заключался в том, чтобы завершить процесс, вызывающий сбой, и сообщить пользователю сообщение об ошибке Floating point exception
.
Перехваты в режиме ядра более проблематичны.ОС не так легко предпринять корректирующие действия, если она сама виновата.Для системного процесса нет нижележащего уровня защиты.Вот почему неисправные драйверы устройств могут вызывать реальные проблемы.
При работе на голом металле без удобной защиты операционной системы ситуация очень похожа на описанную выше.Задача номер один для достижения непрерывной правильной работы и состоит в том, чтобы перехватить все потенциальные состояния прерываний до того, как они получат запуск любых прерываний , используя утверждения и обработчики ошибок более высокого уровня. Считайте ловушки последней линией защиты, сетью безопасности, в которую вы намеренно не хотите попасть.
Определение поведения для обработчиков ловушек стоит задуматься,даже если они "никогда не произойдут" .Они будут выполняться, когда что-то пойдет не так неожиданным образом , будь то из-за космических лучей, изменяющих ОЗУ в самом крайнем случае.К сожалению, нет единого правильного ответа на то, что должны делать обработчики ошибок.
Code Complete, 2nd ed:
Наиболее подходящий стиль обработки ошибок зависит от видаПрограммное обеспечение, в котором возникает ошибка, и в целом способствует большей правильности или более надежности .Строго говоря, эти термины находятся на противоположных концах шкалы друг от друга.Правильность означает никогда не возвращать неточный результат;нет результата лучше неточного.Надежность означает всегда пытаться сделать что-то, что позволит программному обеспечению продолжать работать, даже если это иногда приводит к неточным результатам.
Очевидно, что обработка ошибок моей операционной системы разработана с учетом надежности;Я могу выполнить некорректный код и делать практически все что угодно без сбоев системы.Проектирование исключительно для надежности означало бы попытку восстановления всякий раз, когда это возможно, и, если все остальное не удалось, сбросьте.Это подходящий подход, если ваш продукт, например, игрушка.
Для приложений, критически важных для безопасности, нужно немного больше паранойи, и вместо этого следует отдавать предпочтение правильности;при обнаружении неисправности запишите журнал ошибок, завершение работы.Мы не хотим, чтобы наше отделение лучевой терапии выбирало уровни дозировки из недопустимых значений мусора.