|
Отладка начинается с того момента, когда перестают выдаваться сообщения о синтаксических ошибках. В начале процесса отладки надо использовать простые тестовые данные. Если при этом получаются верные результаты, следует переходить к тестированию программы посредством более сложных данных. В случае если результаты неверны, возможны следующие ситуации:
1. Синтаксических ошибок нет, но программа не скомпилирована.
2. Программа скомпилирована, работает, но не выдает результатов.
3. Программа скомпилирована, работает, но происходит преждевременный останов.
4. Программа скомпилирована, работает, но выдает неправильные результаты.
5. Программа зациклилась.
СЛУЧАЙ 1. КОМПИЛИРОВАНИЕ НЕ ЗАВЕРШЕНО
Подобная ситуация встречается сравнительно редко и свидетельствует о наличии какой-то принципиальной ошибки в программе. В этом случае обычно появляются сообщения о тех или иных системных ошибках, которые можно использовать в качестве вспомогательного средства для выявления имеющейся ошибки. Однако, как правило, интерпретация таких сообщений трудна и требует большого практического опыта.
При отсутствии навыков работы с конкретной вычислительной системой часто бывает затруднительно выяснить причину происшедшего аварийного останова (авоста). Поэтому, если вы не знаете, что означает конкретный останов, поинтересуйтесь у своих более осведомленных коллег. Хороший метод накопления опыта в отношении системных остановов состоит в том, чтобы вести книгу их регистрации с указанием выясненных причин. В противном случае легко забыть ситуации, создававшиеся в прошлом, так как в большинстве своем системные остановы — явление редкое.
Если же рядом не оказалось никого, кто мог бы вам помочь, лучше всего попытаться изолировать ошибку. Для этого программу разбивают на более мелкие самостоятельные сегменты и делают попытку компилировать их по отдельности. В таком сегментированном виде программа сохраняется до момента окончания компилирования всех сегментов. После этого начинается их последовательная увязка, и сегменты присоединяются до тех пор, пока не выявится факт прекращения компилирования программы; последний добавленный сегмент и будет тем блоком, который содержит ошибку. Путем тщательного анализа этого дефектного блока или посредством дальнейшего его сегментирования можно в конце концов выявить тот оператор, который препятствует компилированию программы. Однако применение описанного метода нежелательно, и он должен использоваться лишь в крайних случаях: предпочтительнее обратиться за помощью к своим более опытным товарищам по работе.
СЛУЧАЙ 2. БЕЗРЕЗУЛЬТАТНАЯ РАБОТА ПРОГРАММЫ
Когда программа работает, но не выдает никаких результатов, от нее мало проку, хотя это и некий прогресс по сравнению с первым случаем. Такие неполадки могут вызываться какими-либо логическими или системными ошибками. Примером логической ошибки может служить ситуация, когда программа начинает работу и сразу уходит на ветвь окончания выполнения задания, не сформировав никакого результата для выдачи. Ошибки подобного рода могут быть обнаружены с помощью методов, описанных ниже при- рассмотрении проблемы обнаружения ошибок.
Системная ошибка имеет своей первоосновой некоторую про-граммную ошибку, которая заставляет операционную систему прервать процесс выполнения программы. Сигнал прерывания может исходить от оборудования, самой операционной системы или скомпилированной программы. При этом обычно сообщается код системной ошибки, а может быть, и некоторая информация о ее характере. Однако сообщения о системных ошибках крайне таинственны и не содержат информации о том, где допущена ошибка. Если же при этом выдан какой-либо результат, то имеется все же какое-то указание на местоположение ошибки, и задача сводится к тому, чтобы сузить "подозрительную" область либо посредством использования отладочных протоколов, либо с помощью анализа отладочных результатов. Оба эти вопроса рассматриваются в следующей главе.
К программным ошибкам, приводящим к системным ошибкам, относятся деление на нуль, обращение к области данных и восприятие их как инструкций программы, неверная индексация массива, переполнение или потеря значимости и др.
Обнаружение ошибок в случаях отсутствия результатов работы программы и незавершенного компилирования иногда может оказаться делом чрезвычайно трудным. Один из возможных здесь подходов — перепрограммирование конкретного сегмента некото*
рым другим способом, приводящим к достижению той же цели. Если характер ошибки не очевиден, указанный подход может представлять собой наилегчайший путь к ее устранению. Схож с ним и другой подход, при котором создается несколько копий неправильно функционирующего блока, и в них осуществляются различные изменения, сопровождаемые повторными прогонами программы. Этот процесс повторяется до тех пор, пока ошибка не исчезнет или не окажется изолированной.
СЛУЧАЙ 3. ПРЕЖДЕВРЕМЕННЫЙ ОСТАНОВ
Эта ситуация характерна тем, что программа компилируется до конца, начинается ее выполнение, выдаются какие-то результаты, но затем работа программы прекращается раньше, чем это должно быть. Налицо явный прогресс по сравнению с двумя первыми случаями, и положение дел обычно облегчается наличием некоторой информации на выходе. Благодаря этому здесь можно применять традиционные методы отладки.
Ошибки, приводящие к преждевременному прекращению работы программы и сопровождаемые затем сообщением о системной ошибке, называют взрывами (blowup) или воронками (cratered). Это тяжелые ошибки, так как о-ни не дают возможности продолжать выполнение программы. Для их выявления могут использоваться методы, описанные в разделе, посвященном обнаружению ошибок.
СЛУЧАЙ 4. НЕВЕРНЫЕ РЕЗУЛЬТАТЫ
Когда программа работает, но выдает неверные результаты,, опытные программисты всегда считают это удачей. Достижение этой стадии говорит о том, что программа в принципе правильна, а ее логика работает почти точно. Последующие разделы этой главы будут посвящены способам выявления и устранения ошибок,, относящихся к случаю 4.
СЛУЧАЙ 5. ЗАЦИКЛИВАНИЕ
Этот вид ошибок, как правило, обнаружить не так уже трудно. Если сразу не удается распознать, в каком цикле имеется ошибка, следует просто добавить в программу операторы печати до и после каждого "подозрительного" цикла. При этом, однако, следите за тем, чтобы указанные операторы не оказались встроенными внутрь цикла: в противном случае на печать Начнут выдаваться тысячи строк. Добавленные надлежащим образом операторы печати обеспечат выдачу соответствующих данных, которые покажут, из какого цикла при наличии входа не производится выход.
⇐4.11. Синтаксические ошибки || Оглавление || 4.13. Общие рекомендации⇒
|