Страница 22 из 27
Низкий уровень. Иногда драйверы устройств содержат такие серьезные ошибки, что программа просто не может продолжаться, пока они не будут исправ- лены. Когда такие ошибки происходят, то система вызывает обработ- чик критических ошибок. Он может вступать в действие как для стандартных устройств, так и для установленных драйверов. Пользо- ватель наиболее часто сталкивается с ним, когда пытается произ- вести дисковую операцию с дисководом, у которого открыта дверца. В этом случае появляется сообщение: "Not ready error reading drive A - Abort, Retry, Ignore?" Обработчик критических ошибок может быть переписан, чтобы он лучше обрабатывал устройства, для которых Вы создали устанавли- ваемые драйверы. Вектор прерывания 24H указывает на стандартную процедуру MS DOS, но Вы можете перенаправить вектор на свою про- цедуру. При вызове этой процедуры старший бит AH содержит 0 если ошибка произошла на блочном устройстве и 1, если на символьном. BP:SI указывают на заголовок драйвера виновного устройства, кото- рый может дать дополнительную информацию. Восемь байтов, начиная со смещения AH в заголовке содержат имя устройства, а обработчик критичеких ошибок помещает код ошибки длиной в слово в DI. Вот кодовые номера (они не представляют битовых позиций):
Код Проблема
0 попытка писать на диск, защищенный от записи 1 неизвестное устройство 2 накопитель не готов 3 неизвестная команда 4 ошибка обмена данными 5 неверная длина запроса 6 ошибка поиска
7 неизвестный тип носителя 8 сектор не найден 9 нет бумаги в принтере A ошибка при записи B ошибка при чтении C общая ошибка
В случае дисковой ошибки AL содержит номер накопителя, на котором произошла ошибка (0 = A, 1 = B и т.д.), а биты 2-0 AH индицируют тип ошибки. Бит 0 устанавливается, если ошибка произошла во время операции записи, и сбрасывается - если при чтении. Биты 2-1 со- держат информацию о том, в каком месте диска произошла ошибка, давая 00 - для начальных секторов DOS, 01 - для FAT, 10 - для каталога и 11 - для всего остального диска. Имеется три способа, которыми программа может восстановиться после критической ошибки:
1. Можно попросить пользователя устранить причину ошибки (напри- мер, закрыть дверцу накопителя), после чего система предоставит устройству возможность повторить операцию. 2. Управление может быть возвращено инструкции, следующей за INT 21H, которая сделала попытку обратиться к драйверу. 3. Программа может завершиться и вернуть управление системе.
Ваша процедура обработки ошибок может восстановить ситуацию, выдав инструкцию IRET, после того, как она поместила 0 в AL, чтобы игнорировать ошибку, 1 - чтобы повторить операцию и 2 - чтобы завершить программу. Если Вы хотите, чтобы Ваша процедура провела восстановление сама, то она должна восстановить регистры выполняемой программы из стека, а затем удалить со стека все, кроме последних трех слов. После этого инструкция IRET возвратит управление программе, хотя сама система останется в нестабильном состоянии до тех пор, пока она не сделает вызов функции с номером большим, чем 12. Вот конфигурация стека (начиная сверху до низа) когда вызывается обработчик критических ошибок:
Адрес возврата обработчика ошибок: IP, CS, флаги
Пользовательские регистры задачи, AX, BX, CX, DX, SI, DI, BP, из которой был вызван драйвер: DS, ES, IP, CS, флаги
MS DOS обрабатывает также многие некритические ошибки. Сюда включаются коды ошибок, которые могут возвращаться в регистрах, когда вызывалась функция DOS. Эти коды обсуждаются в данной книге
в тех местах, в которых описываются соответствующие функции. Однако имейте ввиду, что начиная с версии 3.0 MS DOS возвращает расширенные коды ошибок для функций, использующих FCB или деск- рипторы файлов. Когда при выполнении одной из этих функций уста- навливается флаг переноса, то в AX возвращается обычный код ошиб- ки. Дополнительный расширенный код доступен через прерывание 59H, если в BX поместить 0. Эта функция сообщает также о критических ошибках и она может быть использована из обработчика критических ошибок, вызываемого через прерывание 24H. Функция помещает в AX код ошибки, взятый из обычного списка знакомых кодов ошибок (например, "недостаточно памяти") или один из новых кодов (например, "ограничение доступа" для многопользо- вательской системы). BH возвращает код класса ошибки, указывая какого типа ошибка произошла. Например, код 1 указывает, что исчерпаны ресурсы, т.е. что память, файловые буфера или что-то еще израсходовано. Другие классы могут указывать на программные ошибки, проблемы с носителями, форматированием и т.д. BL содержит код, предполагающий действие для восстановления, такое как "пов- торить", "прекратить" или "запросить у пользователя". Наконец, CH возвращает число, определяющее место где возникли проблемы: на блочном устройстве, на символьном, в памяти? Данные для этих кодов ошибок весьма обширны. Полную информацию о них см. в Техническом руководстве по MS DOS 3.0. Поскольку предполагается, что MS DOS 3.0 не будет использоваться на маши- нах, более ранних, чем AT, то использование этих кодов ограничи- вает совместимость Ваших программ. Тем не менее, набор процедур, предназначенный только для MS DOS 3.0 может дополняться поверх обычных процедур обработки ошибок. В [1.1.3] показано как прог- рамма может определить версию MS DOS, в которой она работает. Наконец, имейте ввиду, что процесс может передавать код завер- шения вызвавшему его процессу. Термин процесс относится к взаимо- действующим программам. Например, когда одна программа загружает и запускает другую с помощью функции EXEC, то запускаемая прог- рамма называется потомком, а запускающая программа - родителем. Родителю может потребоваться информация о том, как завершился потомок. Чтобы использовать эту возможность, поместите желаемый код завершения в AL и выполните функцию 4CH прерывания 21H для завершения программы. Когда управление будет возвращено родителю, то он выполнит функцию 4DH прерывания 21H (без входных регистров) и в AL будет получен код завершения, который может затем быть проанализирован. Кроме того, AH будет содержать информацию о том, как завершился потомок: 0 - для нормального завершения, 1 - по Ctrl-Break, 2 - по критической ошибке устройства и 3 - с помощью функции 31H, оставляющей задачу резидентной. Если программа завершилась с помощью этой функции (а не 20H - см. обсуждение в [1.3.4]), то MS DOS получает код выхода и он может быть включен в обработку командным файлом с помощью подко- манды IF. Эта подкоманда позволяет условное исключение других команд из командного файла. Код выхода рассматривается как номер ERRORLEVEL и условные операции выполняются в зависимости от того, больше он или нет определенного числа. С помощью этой возможности командные файлы могут прекращать обработку и выводить сообющение о возникновении ошибки в одной из запущенных программ. Более подробная информация приведена в разделе "Команды пакетной обра- ботки" руководства по операционной системе.
|