Меню

Отладка программы классификация ошибок

  1. Отладка по – классификация ошибок: ошибки компиляции, компоновки, выполнения; причины ошибок выполнения.

Отладка-это
процесс локализации и исправления
ошибок, обнаруженных при тестировании
программного обеспечения. Локализацией
называют
процесс определения оператора программы,
выполнение которого вызвало нарушение
нормального вычислительного процесса.
До исправления ошибки необходимо
определить ее причину,
т. е. определить оператор или фрагмент,
содержащие ошибку. Причины ошибок могут
быть как очевидны, так и очень глубоко
скрыты.

В целом сложность
отладки обусловлена следующими причинами:

• требует от
программиста глубоких знаний специфики
управления используемыми техническими
средствами, операционной системы, среды
и языка программирования, реализуемых
процессов, природы и специфики различных
ошибок, методик отладки и соответствующих
программных средств;

• психологически
дискомфортна, так как необходимо искать
собственные ошибки и, как правило, в
условиях ограниченного времени;

• возможно
взаимовлияние ошибок в разных частях
программы, например, за счет затирания
области памяти одного модуля другим
из-за ошибок адресации;

• отсутствуют
четко сформулированные методики отладки.

В соответствии с
этапом обработки, на котором проявляются
ошибки, различаю:

синтаксические
ошибки

ошибки, фиксируемые компилятором
(транслятором, интерпретатором) при
выполнении синтаксического и частично
семантического анализа программы;

ошибки компоновки
— ошибки,
обнаруженные компоновщиком (редактором
связей) при объединении модулей программы;

ошибки выполнения
— ошибки,
обнаруженные операционной системой,
аппаратными средствами или пользователем
при выполнении программы.

Синтаксические
ошибки.
Синтаксические
ошибки относят к группе самых простых,
так как синтаксис языка, как правило,
строго формализован, и ошибки сопровождаются
развернутым комментарием с указанием
ее местоположения. Определение причин
таких ошибок, как правило, труда не
составляет, и даже при нечетком знании
правил языка за несколько прогонов
удается удалить все ошибки данного
типа.

Следует иметь в
виду, что чем лучше формализованы правила
синтаксиса языка, тем больше ошибок из
общего количества может обнаружить
компилятор и, соответственно, меньше
ошибок будет обнаруживаться на следующих
этапах. В связи с этим говорят о языках
программирования с защищенным синтаксисом
и с незащищенным синтаксисом. К первым,
безусловно, можно отнести Pascal, имеющий
очень простой и четко определенный
синтаксис, хорошо проверяемый при
компиляции программы, ко вторым — Си со
всеми его модификациями. Чего стоит
хотя бы возможность выполнения
присваивания в условном операторе в
Си, например: if (c = n) x = 0; /* в данном случае
не проверятся равенство с и n, а выполняется
присваивание с значения n, после чего
результат операции сравнивается с
нулем, если программист хотел выполнить
не присваивание, а сравнение, то эта
ошибка будет обнаружена только на этапе
выполнения при получении результатов,
отличающихся от ожидаемых */

Ошибки компоновки.
Ошибки
компоновки, как следует из названия,
связаны с проблемами,

обнаруженными при
разрешении внешних ссылок. Например,
предусмотрено обращение к подпрограмме
другого модуля, а при объединении модулей
данная подпрограмма не найдена или не
стыкуются списки параметров. В большинстве
случаев ошибки такого рода также удается
быстро локализовать и устранить.

Ошибки выполнения.
К самой
непредсказуемой группе относятся ошибки
выполнения. Прежде всего они могут иметь
разную природу, и соответственно
по-разному проявляться. Часть ошибок
обнаруживается и документируется
операционной системой. Выделяют четыре
способа проявления таких ошибок:

• появление
сообщения об ошибке, зафиксированной
схемами контроля выполнения машинных
команд, например, переполнении разрядной
сетки, ситуации «деление на ноль»,
нарушении адресации и т. п.;

• появление
сообщения об ошибке, обнаруженной
операционной системой, например,
нарушении защиты памяти, попытке записи
на устройства, защищенные от записи,
отсутствии файла с заданным именем и
т. п.;

• «зависание»
компьютера, как простое, когда удается
завершить программу без перезагрузки
операционной системы, так и «тяжелое»,
когда для продолжения работы необходима
перезагрузка;

• несовпадение
полученных результатов с ожидаемыми.

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

• неверное
определение исходных данных,

• логические
ошибки,

• накопление
погрешностей результатов вычислений.

Неверное
определение исходных данных

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

Логические ошибки
имеют разную природу. Так они могут
следовать из ошибок, допущенных при
проектировании, например, при выборе
методов, разработке алгоритмов или
определении структуры классов, а могут
быть непосредственно внесены при
кодировании модуля.

К последней группе
относят:

ошибки
некорректного использования переменных
,
например, неудачный выбор типов данных,
использование переменных до их
инициализации, использование индексов,
выходящих за границы определения
массивов, нарушения соответствия типов
данных при использовании явного или
неявного переопределения типа данных,
расположенных в памяти при использовании
нетипизированных переменных, открытых
массивов, объединений, динамической
памяти, адресной арифметики и т. п.;

ошибки
вычислений
,
например, некорректные вычисления над
неарифметическими переменными,
некорректное использование целочисленной
арифметики, некорректное преобразование
типов данных в процессе вычислений,
ошибки, связанные с незнанием приоритетов
выполнения операций для арифметических
и логических выражений, и т. п.;

ошибки
межмодульного интерфейса
,
например, игнорирование системных
соглашений, нарушение типов и
последовательности при передачи
параметров, несоблюдение единства
единиц измерения формальных и фактических
параметров, нарушение области действия
локальных и глобальных переменных;

• другие ошибки
кодирования
,
например, неправильная реализация
логики программы при кодировании,
игнорирование особенностей или
ограничений конкретного языка
программирования.

Накопление
погрешностей

результатов числовых вычислений
возникает, например, при некорректном
отбрасывании дробных цифр чисел,
некорректном использовании приближенных
методов вычислений, игнорировании
ограничения разрядной сетки представления
вещественных чисел в ЭВМ и т. п.

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

• опосредованного
проявления ошибок;

• возможности
взаимовлияния ошибок;

• возможности
получения внешне одинаковых проявлений
разных ошибок;

• отсутствия
повторяемости проявлений некоторых
ошибок от запуска к запуску – так
называемые стохастические ошибки;

• возможности
устранения внешних проявлений ошибок
в исследуемой ситуации при внесении
некоторых изменений в программу,
например, при включении в программу
диагностических фрагментов может
аннулироваться или измениться внешнее
проявление ошибок;

• написания
отдельных частей программы разными
программистами.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Отладка программы — один их самых сложных этапов разработки программного обеспечения, требующий глубокого знания:

специфики управления используемыми техническими средствами,

операционной системы,

среды и языка программирования,

реализуемых процессов,

природы и специфики различных ошибок,

методик отладки и соответствующих программных средств. 

Отладка — это процесс локализации и исправления ошибок, обнаруженных при тестировании программного обеспечения. Локализацией называют процесс определения оператора программы, выполнение которого вызвало нарушение нормального вычислительного процесса. Доя исправления ошибки необходимо определить ее причину, т. е. определить оператор или фрагмент, содержащие ошибку. Причины ошибок могут быть как очевидны, так и очень глубоко скрыты.

Вцелом сложность отладки обусловлена следующими причинами:

требует от программиста глубоких знаний специфики управления используемыми техническими средствами, операционной системы, среды и языка программирования, реализуемых процессов, природы и специфики различных ошибок, методик отладки и соответствующих программных средств;

психологически дискомфортна, так как необходимо искать собственные ошибки и, как правило, в условиях ограниченного времени;

возможно взаимовлияние ошибок в разных частях программы, например, за счет затирания области памяти одного модуля другим из-за ошибок адресации;

отсутствуют четко сформулированные методики отладки.

Всоответствии с этапом обработки, на котором проявляются ошибки, различают (рис. 10.1):


    синтаксические ошибки — ошибки, фиксируемые компилятором (транслятором, интерпретатором) при выполнении синтаксического и частично семантического анализа программы; ошибки компоновки — ошибки, обнаруженные компоновщиком (редактором связей) при объединении модулей программы;

    ошибки выполнения — ошибки, обнаруженные операционной системой, аппаратными средствами или пользователем при выполнении программы.

Синтаксические ошибки. Синтаксические ошибки относят к группе самых простых, так как синтаксис языка, как правило, строго формализован, и ошибки сопровождаются развернутым комментарием с указанием ее местоположения. Определение причин таких ошибок, как правило, труда не составляет, и даже при нечетком знании правил языка за несколько прогонов удается удалить все ошибки данного типа.

Следует иметь в виду, что чем лучше формализованы правила синтаксиса языка, тем больше ошибок из общего количества может обнаружить компилятор и, соответственно, меньше ошибок будет обнаруживаться на следующих этапах. В связи с этим говорят о языках программирования с защищенным синтаксисом и с незащищенным синтаксисом. К первым, безусловно, можно отнести Pascal, имеющий очень простой и четко определенный синтаксис, хорошо проверяемый при компиляции программы, ко вторым — Си со всеми его модификациями. Чего стоит хотя бы возможность выполнения присваивания в условном операторе в Си, например:

if (c = n) x = 0; /* в данном случае не проверятся равенство с и n, а выполняется присваивание с значения n, после чего результат операции сравнивается с нулем, если программист хотел выполнить не присваивание, а сравнение, то эта ошибка будет обнаружена только на этапе выполнения при получении результатов, отличающихся от ожидаемых */ 

Ошибки компоновки. Ошибки компоновки, как следует из названия, связаны с проблемами,

обнаруженными при разрешении внешних ссылок. Например, предусмотрено обращение к подпрограмме другого модуля, а при объединении модулей данная подпрограмма не найдена или не стыкуются списки параметров. В большинстве случаев ошибки такого рода также удается быстро локализовать и устранить.

    Ошибки выполнения. К самой непредсказуемой группе относятся ошибки выполнения. Прежде всего они могут иметь разную природу, и соответственно по-разному проявляться. Часть ошибок обнаруживается и документируется операционной системой. Выделяют четыре способа проявления таких ошибок:

• появление сообщения об ошибке, зафиксированной схемами контроля выполнения машинных команд, например, переполнении разрядной сетки, ситуации «деление на ноль», нарушении адресации и т. п.;

появление сообщения об ошибке, обнаруженной операционной системой, например, нарушении защиты памяти, попытке записи на устройства, защищенные от записи, отсутствии файла с заданным именем и т. п.;

«зависание» компьютера, как простое, когда удается завершить программу без перезагрузки операционной системы, так и «тяжелое», когда для продолжения работы необходима перезагрузка;

несовпадение полученных результатов с ожидаемыми.

Примечание. Отметим, что, если ошибки этапа выполнения обнаруживает пользователь, то в двух первых случаях, получив соответствующее сообщение, пользователь в зависимости от своего характера, степени необходимости и опыта работы за компьютером, либо попробует понять, что произошло, ища свою вину, либо обратится за помощью, либо постарается никогда больше не иметь дела с этим продуктом. При «зависании» компьютера пользователь может даже не сразу понять, что происходит что-то не то, хотя его печальный опыт и заставляет волноваться каждый раз, когда компьютер не выдает быстрой реакции на введенную команду, что также целесообразно иметь в виду. Также опасны могут быть ситуации, при которых пользователь получает неправильные результаты и использует их в своей работе.

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

неверное определение исходных данных,

логические ошибки,

накопление погрешностей результатов вычислений (рис. 10.2).

Н е в е р н о е о п р е д е л е н и е и с х о д н ы х д а н н ы х происходит, если возникают любые ошибки при выполнении операций ввода-вывода: ошибки передачи, ошибки преобразования, ошибки перезаписи и ошибки данных. Причем использование специальных технических средств и программирование с защитой от ошибок (см.§ 2.7) позволяет обнаружить и предотвратить только часть этих ошибок, о чем безусловно не следует забывать.

Л о г и ч е с к и е о ш и б к и имеют разную природу. Так они могут следовать из ошибок, допущенных при проектировании, например, при выборе методов, разработке алгоритмов или определении структуры классов, а могут быть непосредственно внесены при кодировании модуля.

Кпоследней группе относят:

ошибки некорректного использования переменных, например, неудачный выбор типов данных, использование переменных до их инициализации, использование индексов, выходящих за границы определения массивов, нарушения соответствия типов данных при использовании явного или неявного переопределения типа данных, расположенных в памяти при использовании нетипизированных переменных, открытых массивов, объединений, динамической памяти, адресной арифметики и т. п.;

ошибки вычислений, например, некорректные вычисления над неарифметическими переменными, некорректное использование целочисленной арифметики, некорректное преобразование типов данных в процессе вычислений, ошибки, связанные с незнанием приоритетов выполнения операций для арифметических и логических выражений, и т. п.;

ошибки межмодульного интерфейса, например, игнорирование системных соглашений, нарушение типов и последовательности при передачи параметров, несоблюдение единства единиц измерения формальных и фактических параметров, нарушение области действия локальных и глобальных переменных;

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

На к о п л е н и е п о г р е ш н о с т е й результатов числовых вычислений возникает, например, при некорректном отбрасывании дробных цифр чисел, некорректном использовании приближенных методов вычислений, игнорировании ограничения разрядной сетки представления вещественных чисел в ЭВМ и т. п.

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

опосредованного проявления ошибок;

возможности взаимовлияния ошибок;

возможности получения внешне одинаковых проявлений разных ошибок;

отсутствия повторяемости проявлений некоторых ошибок от запуска к запуску – так называемые стохастические ошибки;

возможности устранения внешних проявлений ошибок в исследуемой ситуации при внесении некоторых изменений в программу, например, при включении в программу диагностических фрагментов может аннулироваться или измениться внешнее проявление ошибок;

написания отдельных частей программы разными программистами.

Методы отладки программного обеспечения

Отладка программы в любом случае предполагает обдумывание и логическое осмысление всей имеющейся информации об ошибке. Большинство ошибок можно обнаружить по косвенным признакам посредством тщательного анализа текстов программ и результатов тестирования без получения дополнительной информации. При этом используют различные методы:

ручного тестирования;

индукции;

дедукции;

обратного прослеживания.

Метод ручного тестирования. Это — самый простой и естественный способ данной группы. При обнаружении ошибки необходимо выполнить тестируемую программу вручную, используя тестовый набор, при работе с которым была обнаружена ошибка.

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

Данный метод часто используют как составную часть других методов отладки.

Метод индукции. Метод основан на тщательном анализе симптомов ошибки, которые могут проявляться как неверные результаты вычислений или как сообщение об ошибке. Если компьютер просто «зависает», то фрагмент проявления ошибки вычисляют, исходя из последних полученных результатов и действий пользователя. Полученную таким образом информацию организуют и тщательно изучают, просматривая соответствующий фрагмент программы. В результате этих действий выдвигают гипотезы об ошибках, каждую из которых проверяют. Если гипотеза верна, то детализируют информацию об ошибке, иначе — выдвигают другую гипотезу. Последовательность выполнения отладки методом индукции показана на рис. 10.3 в виде схемы алгоритма.

Самый ответственный этап — выявление симптомов ошибки. Организуя данные об ошибке, целесообразно записать все, что известно о ее проявлениях, причем фиксируют, как ситуации, в которых фрагмент с ошибкой выполняется нормально, так и ситуации, в которых ошибка проявляется. Если в результате изучения данных никаких гипотез не появляется, то необходима дополнительная информация об ошибке. Дополнительную информацию можно получить, например, в результате выполнения схожих тестов.

В процессе доказательства пытаются выяснить, все ли проявления ошибки объясняет данная гипотеза, если не все, то либо гипотеза не верна, либо ошибок несколько.

Метод дедукции. По методу дедукции вначале формируют множество причин, которые могли бы вызвать данное проявление ошибки. Затем анализируя причины, исключают те, которые противоречат имеющимся данным. Если все причины исключены, то следует выполнить дополнительное тестирование исследуемого фрагмента. В противном случае наиболее вероятную гипотезу пытаются доказать. Если гипотеза объясняет полученные признаки ошибки, то ошибка найдена, иначе — проверяют следующую причину (рис. 10.4).

Метод обратного прослеживания. Для небольших программ эффективно применение метода обратного прослеживания. Начинают с точки вывода неправильного результата. Для этой точки строится гипотеза о значениях основных переменных, которые могли бы привести к получению имеющегося результата. Далее, исходя из этой гипотезы, делают предложения о значениях переменных в предыдущей точке. Процесс продолжают, пока не обнаружат причину ошибки.

Отладка программы призвана выискивать «вредителей» кода и устранять их. За это отвечают отладчик и журналирование для вывода сведений о программе.

В предыдущей части мы рассмотрели исходный код и его составляющие.

После того, как вы начнете проверять фрагменты кода или попытаетесь решить связанные с ним проблемы, вы очень скоро поймете, что существуют моменты, когда программа крашится, прерывается и прекращает работу.

Отладка программы

Это часто вызвано ошибками, известными как дефекты или исключительные ситуации во время выполнения. Акт обнаружения и удаления ошибок из нашего кода – это отладка программы. Вы лучше разберетесь в отладке на практике, используя ее как можно чаще. Мы не только отлаживаем собственный код, но и порой дебажим написанное другими программистами.

Для начала необходимо рассортировать общие ошибки, которые могут возникнуть в исходном коде.

отладка программы

Синтаксические ошибки

Эти эрроры не позволяют скомпилировать исходный код на компилируемых языках программирования. Они обнаруживаются во время компиляции или интерпретации исходного кода. Они также могут быть легко обнаружены статическими анализаторами (линтами). Подробнее о линтах мы узнаем немного позже.

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

Семантические ошибки

Отладка программы может потребоваться и по причине семантических ошибок, также известных как логические. Они являются наиболее сложными из всех, потому что не могут быть легко обнаружены. Признак того, что существует семантическая ошибка, – это когда программа запускается, отрабатывает, но не дает желаемого результата.

Рассмотрим данный пример:

3 + 5 * 6

По порядку приоритета, называемому старшинством операции, с учетом математических правил мы ожидаем, что сначала будет оценена часть умножения, и окончательный результат будет равен 33. Если программист хотел, чтобы сначала происходило добавление двух чисел, следовало поступить иначе. Для этого используются круглые скобки, которые отвечают за смещение приоритетов в математической формуле. Исправленный пример должен выглядеть так:

(3 + 5) * 6

3 + 5, заключенные в скобки, дадут желаемый результат, а именно 48.

Ошибки в процессе выполнения

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

Вот хороший пример:

input = 25
x = 0.8/(Math.sqrt(input) - 5)

Фрагмент кода выше будет скомпилирован успешно, но input 25 приведет к ZeroDivisionError. Это ошибка во время выполнения. Другим популярным примером является StackOverflowError или IndexOutofBoundError. Важно то, что вы идентифицируете эти ошибки и узнаете, как с ними бороться.

Существуют ошибки, связанные с тем, как ваш исходный код использует память и пространство на платформе или в среде, в которой он запущен. Они также являются ошибками во время выполнения. Такие ошибки, как OutOfMemoryErrorand и HeapError обычно вызваны тем, что ваш исходный код использует слишком много ресурсов. Хорошее знание алгоритмов поможет написать код, который лучше использует ресурсы. В этом и заключается отладка программы.

Процесс перезаписи кода для повышения производительности называется оптимизацией. Менее популярное наименование процесса – рефакторинг. Поскольку вы тратите больше времени на кодинг, то должны иметь это в виду.

Отладка программы

Вот несколько советов о том, как правильно выполнять отладку:

  1. Использовать Linters. Linters – это инструменты, которые помогают считывать исходный код, чтобы проверить, соответствует ли он ожидаемому стандарту на выбранном языке программирования. Существуют линты для многих языков.
  2. Превалирование IDE над простыми редакторами. Вы можете выбрать IDE, разработанную для языка, который изучаете. IDE – это интегрированные среды разработки. Они созданы для написания, отладки, компиляции и запуска кода. Jetbrains создают отличные IDE, такие как Webstorm и IntelliJ. Также есть NetBeans, Komodo, Qt, Android Studio, XCode (поставляется с Mac), etc.
  3. Чтение кода вслух. Это полезно, когда вы ищете семантическую ошибку. Читая свой код вслух, есть большая вероятность, что вы зачитаете и ошибку.
  4. Чтение логов. Когда компилятор отмечает Error, обязательно посмотрите, где он находится.

Двигаемся дальше

Поздравляем! Слово «ошибка» уже привычно для вас, равно как и «отладка программы». В качестве новичка вы можете изучать кодинг по книгам, онлайн-урокам или видео. И даже чужой код вам теперь не страшен 🙂

В процессе кодинга измените что-нибудь, чтобы понять, как он работает. Но будьте уверены в том, что сами написали.

Викторина

  1. Какая ошибка допущена в фрагменте кода Python ниже?
items = [0,1,2,3,4,5]
print items[8]
//комментарий: элементы здесь представляют собой массив с шестью элементами. Например, чтобы получить 4-й элемент, вы будете использовать [3]. Мы начинаем отсчет с 0.
  1. Какая ошибка допущена в фрагменте кода Python ниже?
input = Hippo'
if input == 'Hippo':
  print 'Hello, Hippo'

Ответы на вопросы

  1. Ошибка выполнения: ошибка индекса вне диапазона.

2. Синтаксическая ошибка: Отсутствует стартовая кавычка в первой строке.

Привет, Вы узнаете про виды ошибок программного обеспечения, Разберем основные ее виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое
виды ошибок программного обеспечения, принципы отладки , настоятельно рекомендую прочитать все из категории Качество и тестирование программного обеспечения. Quality Assurance..

1. Отладка программы

Отладка, как мы уже говорили, бывает двух видов:
Синтаксическая отладка. Синтаксические ошибки выявляет компилятор, поэтому исправлять их достаточно легко.
Семантическая (смысловая) отладка. Ее время наступает тогда, когда синтаксических ошибок не осталось, но результаты программа выдает неверные. Здесь компилятор сам ничего выявить не сможет, хотя в среде программирования обычно существуют вспомогательные средства отладки, о которых мы еще поговорим.
Отладка — это процесс локализации и исправления ошибок в программе.

Как бы тщательно мы ни писали, отладка почти всегда занимает больше времени, чем программирование.

2. Локализация ошибок

Локализация — это нахождение места ошибки в программе.

В процессе поиска ошибки мы обычно выполняем одни и те же действия:

  • прогоняем программу и получаем результаты;
  • сверяем результаты с эталонными и анализируем несоответствие;
  • выявляем наличие ошибки, выдвигаем гипотезу о ее характере и месте в программе;
  • проверяем текст программы, исправляем ошибку, если мы нашли ее правильно.

Способы обнаружения ошибки:

  • Аналитический — имея достаточное представление о структуре программы, просматриваем ее текст вручную, без прогона.
  • Экспериментальный — прогоняем программу, используя отладочную печать и средства трассировки, и анализируем результаты ее работы.

Оба способа по-своему удобны и обычно используются совместно.

3.
принципы отладки

Принципы локализации ошибок:

  • Большинство ошибок обнаруживается вообще без запуска программы — просто внимательным просматриванием текста.
  • Если отладка зашла в тупик и обнаружить ошибку не удается, лучше отложить программу. Когда глаз «замылен», эффективность работы упорно стремится к нулю.
  • Чрезвычайно удобные вспомогательные средства — это отладочные механизмы среды разработки: трассировка, промежуточный контроль значений. Можно использовать даже дамп памяти, но такие радикальные действия нужны крайне редко.
  • Экспериментирования типа «а что будет, если изменить плюс на минус» — нужно избегать всеми силами. Обычно это не дает результатов, а только больше запутывает процесс отладки, да еще и добавляет новые ошибки.

Принципы исправления ошибок еще больше похожи на законы Мерфи:

  • Там, где найдена одна ошибка, возможно, есть и другие.
  • Вероятность, что ошибка найдена правильно, никогда не равна ста процентам.
  • Наша задача — найти саму ошибку, а не ее симптом.

Это утверждение хочется пояснить. Если программа упорно выдает результат 0,1 вместо эталонного нуля, простым округлением вопрос не решить. Если результат получается отрицательным вместо эталонного положительного, бесполезно брать его по модулю — мы получим вместо решения задачи ерунду с подгонкой.
Исправляя одну ошибку, очень легко внести в программу еще парочку. «Наведенные» ошибки — настоящий бич отладки.
Исправление ошибок зачастую вынуждает нас возвращаться на этап составления программы. Это неприятно, но порой неизбежно.

4. Методы отладки

Силовые методы

  • — Использование дампа (распечатки) памяти.Это интересно с познавательной точки зрения: можно досконально разобраться в машинных процессах. Иногда такой подход даже необходим — например, когда речь идет о выделении и высвобождении памяти под динамические переменные с использованием недокументированных возможностей языка. Однако, в большинстве случаев мы получаем огромное количество низкоуровневой информации, разбираться с которой — не пожелаешь и врагу, а результативность поиска — исчезающе низка.
  • — Использование отладочной печати в тексте программы — произвольно и в большом количестве.Получать информацию о выполнении каждого оператора тоже небезынтересно. Но здесь мы снова сталкиваемся со слишком большими объемами информации. Кроме того, мы здорово захламляем программу добавочными операторами, получая малочитабельный текст, да еще рискуем внести десяток новых ошибок.
  • — Использование автоматических средств отладки — трассировки с отслеживанием промежуточных значений переменых.Пожалуй, это самый распространенный способ отладки. Не нужно только забывать, что это только один из способов, и применять всегда и везде только его — часто невыгодно.

Сложности возникают, когда приходится отслеживать слишком большие структуры данных или огромное их число. Еще проблематичнее трассировать проект, где выполнение каждой подпрограммы приводит к вызову пары десятков других. Но для небольших программ трассировки вполне достаточно.

С точки зрения «правильного» программирования силовые методы плохи тем, что не поощряют анализ задачи.

Суммируя свойства силовых методов, получаем практические советы:
— использовать трассировку и отслеживание значений переменных для небольших проектов, отдельных подпрограмм;
— использовать отладочную печать в небольших количества и «по делу»;
— оставить дамп памяти на самый крайний случай.

Метод индукции — анализ программы от частного к общему.
Просматриваем симптомы ошибки и определяем данные, которые имеют к ней хоть какое-то отношение. Затем, используя тесты, исключаем маловероятные гипотезы, пока не остается одна, которую мы пытаемся уточнить и доказать.
Метод дедукции — от общего к частному.
Выдвигаем гипотезу, которая может объяснить ошибку, пусть и не полностью. Затем при помощи тестов эта гипотеза проверяется и доказывается.
Обратное движение по алгоритму.
Отладка начинается там, где впервые встретился неправильный результат. Затем работа программы прослеживается (мысленно или при помощи тестов) в обратном порядке, пока не будет обнаружено место возможной ошибки.
Метод тестирования.

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

var
a, b, c: real;
begin
writeln('Программа находит значение максимального из трех введенных чисел');
write('Введите первое число '); readln(a);
write('Введите второе число '); readln(b);
write('Введите третье число '); readln(c);
if (a>b)and(a>c) then
writeln('Наибольшим оказалось первое число ',a:8:2)
else if (b>a)and(a>c) then
writeln('Наибольшим оказалось второе число ',b:8:2)
else
writeln('Наибольшим оказалось третье число ',b:8:2);
end.

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

Тестовые наборы данных должны учитывать все варианты решения, поэтому выберем следующие наборы чисел:

Данные Ожидаемый результат
a=10; b=-4; c=1 max=a=10
a=-2; b=8; c=4 max=b=8
a=90; b=0; c=90.4 max=c=90.4

В результате выполнения программы мы, однако, получим следующие результаты:
Для a=10; b=-4; c=1:

Наибольшим оказалось первое число 10.00

Для a=-2; b=8; c=4: < pre class=»list»>Наибольшим оказалось третье число 8.00Для a=90; b=0; c=90.4:

Наибольшим оказалось третье число 0.00

Вывод во втором и третьем случаях явно неверен. Будем разбираться.

1. Трассировка и промежуточная наблюдение за переменными

Добавляем промежуточную печать или наблюдение за переменными:

  • — вывод a, b, c после ввода (проверяем, правильно ли получили данные)
  • — вывод значения каждого из условий (проверяем, правильно ли записали условия)

Листинг программы существенно увеличился и стал вот таким:

var
a, b, c: real;
begin
writeln(‘Программа находит значение максимального из трех введенных чисел’);
write(‘Введите первое число ‘); readln(a);
writeln(‘Вы ввели число ‘,a:8:2); {отл.печать}
write(‘Введите второе число ‘); readln(b);
writeln(‘Вы ввели число ‘,b:8:2); {отл.печать}
write(‘Введите третье число ‘); readln(c);
writeln(‘Вы ввели число ‘,c:8:2); {отл.печать}
writeln(‘a>b=’,a>b,’, a>c=’,a>c,’, (a>b)and(a>c)=’,(a>b)and(a>c)); {отл.печать}
if (a>b)and(a>c) then
writeln(‘Наибольшим оказалось первое число ‘,a:8:2)
else begin
writeln(‘b>a=’,b>a,’, b>c=’,b>c,’, (b>a)and(b>c)=’,(b>a)and(b>c)); {отл.печать}
if (b>a)and(a>c) then
writeln(‘Наибольшим оказалось второе число ‘,b:8:2)
else
writeln(‘Наибольшим оказалось третье число ‘,b:8:2);
end;
end.

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

Но давайте считать, что глаз «замылен» совершенно, и найти ошибку не удалось.

Вывод для второго случая получается следующим:

Программа находит значение максимального из трех введенных чисел
Введите первое число -2
Вы ввели число -2.00
Введите второе число 8
Вы ввели число 8.00
Введите третье число 4
Вы ввели число 4.00
a>b=FALSE, a>c=FALSE, (a>b)and(a>c)=FALSE
b>a=TRUE, b>c=TRUE, (b>a)and(b>c)=TRUE
Наибольшим оказалось третье число 8.00

Со вводом все в порядке . Об этом говорит сайт https://intellect.icu . Впрочем, в этом сомнений и так было немного. А вот что касается второй группы операторов печати, то картина вышла интересная: в результате выводится верное число (8.00), но неправильное слово («третье», а не «второе»).

Вероятно, проблемы в выводе результатов. Тщательно проверяем текст и обнаруживаем, что действительно в последнем случае выводится не c, а b. Однако к решению текущей проблемы это не относится: исправив ошибку, мы получаем для чисел -2.0, 8.0, 4.0 следующий результат.

Наибольшим оказалось третье число 4.00

Теперь ошибка локализована до расчетного блока и, после некоторых усилий, мы ее находим и исправляем.

2. Метод индукции

Судя по результатам, ошибка возникает, когда максимальное число — второе или третье (если максимальное — первое, то определяется оно правильно, для доказательства можно програть еще два-три теста).

Просматриваем все, относящееся к переменным b и с. Со вводом никаких проблем не замечено, а что касается вывода — то мы быстро натыкаемся на замену b на с. Исправляем.

Как видно, невыявленные ошибки в программе остаются. Просматриваем расчетный блок: все, что относится к максимальному b (максимум с получается «в противном случае»), и обнаруживаем пресловутую проблему «a>c» вместо «b>c». Программа отлажена.

3. Метод дедукции

Неверные результаты в нашем случае могут получиться из-за ошибки в:

  • — вводе данных;
  • — расчетном блоке;
  • — собственно выводе.

Для доказательства мы можем пользоваться отладочной печатью, трассировкой или просто набором тестов. В любом случае мы выявляем одну ошибку в расчете и одну в выводе.

4. Обратное движение по алгоритму

Зная, что ошибка возникает при выводе результатов, рассматриваем код, начиная с операторов вывода. Сразу же находим лишнюю b в операторе writeln.

Далее, смотрим по конкретной ветке условного оператора, откуда взялся результат. Для значений -2.0, 8.0, 4.0 расчет идет по ветке с условием if (b>a)and(a>c) then… где мы тут же обнаруживаем искомую ошибку.

5. Тестирование

В нашей задаче для самого полного набора данных нужно выбрать такие переменные, что
a > b > c
a > c > b
b > a > c
b > c > a
c > a > b
c > b > a

Анализируя получившиеся в каждом из этих случаев результаты, мы приходим к тому, что проблемы возникают при b>c>a и с — максимальном. Зная эти подробности, мы можем заострить внимание на конкретных участках программы.

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

5. Средства отладки

Помимо методик, хорошо бы иметь представление о средствах, которые помогают нам выявлять ошибки. Это:

1) Аварийная печать — вывод сообщений о ненормальном завершении отдельных блоков и всей программы в целом.

2) Печать в узлах программы — вывод промежуточных значений параметров в местах, выбранных программистом. Обычно, это критичные участки алгоритма (например, значение, от которого зависит дальнейший ход выполнения) или составные части сложных формул (отдельно просчитать и вывести числитель и знаменатель большой дроби).

3) Непосредственное слежение:

  • — арифметическое (за тем, чему равны, когда и как изменяются выбранные переменные),
  • — логическое (когда и как выполняется выбранная последовательность операторов),
  • — контроль выхода индексов за допустимые пределы,
  • — отслеживание обращений к переменным,
  • — отслеживание обращений к подпрограммам,
  • — проверка значений индексов элементов массивов и т.д.

Нынешние среды разработки часто предлагают нам реагировать на возникающую проблему в диалоговом режиме. При этом можно:

  • — просмотреть текущие значения переменных, состояние памяти, участок алгоритма, где произошел сбой;
  • — прервать выполнение программы;
  • — внести в программу изменения и повторно запустить ее (в компиляторных средах для этого потребуется перекомпилировать код, в интерпретаторных выполнение можно продолжить прямо с измененного оператора).

Виды ошибок и основные принципы отладки программного обеспеченияРис Пример отладки приложения

6. Классификация ошибок

Ошибки в программах могут допускаться от самого начального этапа составления алгоритма решения задачи до окончательного оформления программы. Разновидностей ошибок достаточно много. Рассмотрим некоторые группы ошибок и соответствующие примеры:

Виды ошибок и основные принципы отладки программного обеспечения

Если вы удручены тем, что насажали в текст программы глупых ошибок — не расстраивайтесь. Ошибки вообще не бывают умными, хотя и могут относиться к самым разным частям кода:

  • — ошибки обращения к данным,
  • — ошибки описания данных,
  • — ошибки вычислений,
  • — ошибки при сравнении,
  • — ошибки в передаче управления,
  • — ошибки ввода-вывода,
  • — ошибки интерфейса,
  • и т д

Виды ошибок и основные принципы отладки программного обеспечения

Классификация ошибок по этапу обработки программы

Виды ошибок и основные принципы отладки программного обеспечения

рис Классификация ошибок этапа выполнения по возможным причинам

Синтаксические ошибки

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

Примеры синтаксических ошибок :

  • отсутствие знака пунктуации;
  • несоответствие количества открывающих и закрывающих скобок;
  • неправильно сформированный оператор;
  • неправильная запись имени переменной;
  • ошибка в написании служебных слов;
  • отсутствие условия окончания цикла;
  • отсутствие описания массивов и т.п.

Ошибки, которые не обнаруживает транслятор

В случае правильного написания операторов в программе может присутствовать большое количество ошибок, которые транслятор не может обнаружить. Рассмотрим примеры таких ошибок:

Логические ошибки: после проверки заданного условия неправильно указана ветвь алгоритма; неполный перечень возможных условий при решении задачи; один или более блоков алгоритма в программе пропущен.

Ошибки в циклах: неправильно указано начало цикла; неправильно указаны условия окончания цикла; неправильно указано количество повторений цикла; использование бесконечного цикла.

Ошибки ввода-вывода; ошибки при работе с данными: неправильно задан тип данных; организовано считывание меньшего или большего объема данных, чем нужно; неправильно отредактированы данные.

Ошибки в использовании переменных: используются переменных, для которых не указаны начальные значения; ошибочно указана одна переменная вместо другой. Ошибки при работе с массивами: пропущено предварительное обнуление массивов; неправильное описание массивов; индексы массивов следуют в ошибочном порядке.

ошибки безопасности, умышленные и не умышленные уязвимости в системе, открытость к отказам в обслуживании. несанкционированном доступе. екхолы

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

ошибки в архитектуре приложения пприводящие к увеличени технического долга

Методы (пути) снижение ошибок в программировании

  • использование тестиования
  • использование более простых решений
  • использование систем с наименьшим числом составлящих
  • использование ранее использованных и проверенных компонентов
  • использование более квалифицрованных специалистов

7. Советы отладчику

1) Проверяйте тщательнее: ошибка скорее всего находится не в том месте, в котором кажется.

2) Часто оказывается легче выделить те места программы, ошибок в которых нет, а затем уже искать в остальных.

3) Тщательнее следить за объявлениями констант, типов и переменных, входными данными.

4) При последовательной разработке приходится особенно аккуратно писать драйверы и заглушки — они сами могут быть источником ошибок.

5) Анализировать код, начиная с самых простых вариантов. Чаще всего встречаются ошибки:
— значения входных аргументов принимаются не в том порядке,
— переменная не проинициализирована,
— при повторном прохождении модуля, перемен ная повторно не инициализируется,
— вместо предполагаемого полного копирования структуры данных, копируется только верхний уровень (например, вместо создания новой динамической переменной и присваивания ей нужного значения, адрес тупо копируется из уже существующей переменной),
— скобки в сложном выражении расставлены неправильно.

6) При упорной длительной отладке глаз «замыливается». Хороший прием — обратиться за помощью к другому лицу, чтобы не повторять ошибочных рассуждений. Правда, частенько остается проблемой убедить это другое лицо помочь вам.

7) Ошибка, скорее всего окажется вашей и будет находиться в тексте программы. Гораздо реже она оказывается:

  • в компиляторе,
  • операционной системе,
  • аппаратной части,
  • электропроводке в здании и т.д.

Но если вы совершенно уверены, что в программе ошибок нет, просмотрите стандартные модули, к которым она обращается, выясните, не менялась ли версия среды разработки, в конце концов, просто перегрузите компьютер — некоторые проблемы (особенно в DOS-средах, запускаемых из-под Windows) возникают из-за некорректной работы с памятью.

8) Убедитесь, что исходный текст программы соответствует скомпилированному объектному коду (текст может быть изменен, а запускаемый модуль, который вы тестируете — скомпилирован еще из старого варианта).

9) Навязчивый поиск одной ошибки почти всегда непродуктивен. Не получается — отложите задачу, возьмитесь за написание следующего модуля, на худой конец займитесь документированием.

10) Старайтесь не жалеть времени, чтобы уясненить причину ошибки. Это поможет вам:
исправить программу,
обнаружить другие ошибки того же типа,
не делать их в дальнейшем.

11) Если вы уже знаете симптомы ошибки, иногда полезно не исправлять ее сразу, а на фоне известного поведения программы поискать другие ляпы.

12) Самые труднообнаруживаемые ошибки — наведенные, то есть те, что были внесены в код при исправлении других.

8. Тестирование

Тестирование — это выполнение программы для набора проверочных входных значений и сравнение полученных результатов с ожидаемыми.

Цель тестирования — проверка и доказательство правильности работы программы. В противном случае — выявление того, что в ней есть ошибки. Тестирование само не показывает местонахождение ошибки и не указывает на ее причины.
Принципы тестирования.

1) Тест — просчитанный вручную пример выполнения программы от исходных данных до ожидаемых результатов расчета. Эти результаты считаются эталонными.
Полномаршрутным будет такое тестирование, при котором каждый линейный участок программы будет пройден хотя бы при выполнении одного теста.

2) При прогоне программы по тестовым начальным данным, полученные результаты нужно сверить с эталонными и проанализировать разницу, если она есть.

3) При разработке тестов нужно учитывать не только правильные, но и неверные исходные данные.

4) Мы должны проверить программу на нежелательные побочные эффекты при задании некоторых исходных данных (деление на ноль, попытка считывания из несуществующего файла и т.д.).

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

6) Чем больше ошибок в коде мы уже нашли, тем больше вероятность, что мы обнаружим еще не найденные.
Хорошим называют тест, который с большой вероятностью должен обнаруживать ошибки, а удачным — тот, который их обнаружил.

9. Проектирование тестов

Тесты просчитываются вручную, значит, они должны быть достаточно просты для этого.
Тесты должны проверять каждую ветку алгоритма. По возможности, конечно. Так что количество и сложность тестов зависит от сложности программы.
Тесты составляются до кодирования и отладки: во время разработки алгоритма или даже составления математической модели.
Обычно для экономии времени сначала пропускают более простые тесты, а затем более сложные.

Давайте рассмотрим задачу: нужно проверить, попадает ли введенное число в заданный пользователем диапазон.

program Example;
(******************************************************
* Задача: проверить, попадает ли введенное число в *
* заданный пользователем диапазон *
******************************************************)

var
min, max, A, tmp: real;
begin
writeln(‘Программа проверяет, попадают ли введенные пользователем’);
writeln(‘значения в заданный диапазон’);
writeln;
writeln(‘Введите нижнюю границу диапазона ‘); readln(min);
writeln(‘Введите верхнюю границу диапазона ‘); readln(max);
if min>max then begin
writeln(‘Вы перепутали диапазоны, и я их поменяю’);
tmp:=min;
min:=max;
max:=tmp;
end;
repeat
writeln(‘Введите число для проверки (0 — конец работы) ‘); readln(A);
if (A>=min)and(A<=max) then
writeln(‘Число ‘,A,’ попадает в диапазон [‘,min,’..’,max,’]’)
else
writeln(‘Число ‘,A,’ не попадает в диапазон [‘,min,’..’,max,’]’);
until A=0;
writeln;
end.

Если исходить из алгоритма программы, мы должны составить следующие тесты:
ввод границ диапазона
— min< max
— min>max
ввод числа
— A < min (A<>0)
— A > max (A<>0)
— min <= A <= max (A<>0)
— A=0

Как видите, программа очень мала, а тестов для проверки всех ветвей ее алгоритма, требуется довольно много.

10. Стратегии тестирования

1) Тестирование программы как «черного ящика».

Мы знаем только о том, что делает программа, но даже не задумываемся о ее внутренней структуре. Задаем набор входных данных, получаем результаты, сверяем с эталонными.

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

«Черным ящиком» удобно тестировать небольшие подпрограммы.
2) Тестирование программы как «белого ящика».

Здесь перед составлением теста мы изучаем логику программы, ее внутреннюю структуру. Тестирование будет считаться удачным, если проверяет программу по всем направлениям. Однако, как мы уже говорили, это требует огромного количества тестов.

На практике мы, как всегда, совместно используем оба принципа.
3) Тестирование программ модульной структуры.

Мы снова возвращаемся к вопросу о структурном программировании. Если вы помните, программы строятся из модулей не в последнюю очередь для того, чтобы их легко было отлаживать и тестировать. Действительно, структурированную программу мы будем тестировать частями. При этом нам нужно:
строить набор тестов;
комбинировать модули для тестирования.

Такое комбинирование может строиться двумя способами:
Пошаговое тестирование — тестируем каждый модуль, присоединяя его к уже оттестированным. При этом можем соединять части программы сверху вниз (нисходящий способ) или снизу вверх (восходящий).
Монолитное тестирование — каждый модуль тестируется отдельно, а затем из них формируется готовая рабочая программа и тестируется уже целиком.

Чтобы протестировать отдельный модуль, нужен модуль-драйвер (всегда один) и модул и-заглушки (этих может быть несколько).
Модуль-драйвер содержит фиксированные исходные данные. Он вызывает тестируемый модуль и отображает (а возможно, и анализирует) результаты.
Модуль-заглушка нужен, если в тестируемом модуле есть вызовы других. Вместо этого вызова управление передается модулю-заглушке, и уже он имитирует необходимые действия.

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

См. также

  • ошибки в приложениях , bugs , баг репорт , bug report ,
  • Фича
  • GIGO
  • Патч
  • тестирование
  • цикломатическая сложность
  • баг репорт
  • качество программного обеспечения

К сожалению, в одной статье не просто дать все знания про виды ошибок программного обеспечения. Но я — старался.
Если ты проявишь интерес к раскрытию подробностей,я обязательно напишу продолжение! Надеюсь, что теперь ты понял что такое виды ошибок программного обеспечения, принципы отладки
и для чего все это нужно, а если не понял, или есть замечания,
то нестесняся пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории
Качество и тестирование программного обеспечения. Quality Assurance.

Отладка программы: Классификация ошибок

Успешное завершение процесса компиляции не означает, что в программе нет ошибок. Убедиться, что программа работает правильно можно только в процессе проверки ее работоспособности, который называется тестирование.

Обычно программа редко сразу начинает работать так, как надо, или работает правильно только на некотором ограниченном наборе исходных данных. Это свидетельствует о том, что в программе есть алгоритмические ошибки. Процесс поиска и устранение ошибок называется отладкой.

Классификация ошибок.

Ошибки, которые могут быть в программе, принято делить на три группы:

  • синтаксические;
  • ошибки времени выполнения;
  • алгоритмические.

Синтаксические ошибки, их также называют ошибками времени компиляции (Compile-time error), наиболее легко устранимы. Их обнаруживает компилятор, а программисту остается только внести изменения в текст программы и выполнить повторную компиляцию.

Ошибки времени выполнения, в Delphi они называются исключениями (exception), тоже, как правило, легко устранимы. Они обычно проявляются уже при первых запусках программы и во время тестирования.

При возникновении ошибки в программе, запущенной из Delphi, среда разработки прерывает работу программы, о чем свидетельствует заключенное в скобки слово Stopped в заголовке главного окна Delphi, и на экране появляется диалоговое окно, которое содержит сообщение об ошибке и информа-

цию о типе (классе) ошибки. На рис. 13.1 приведен пример сообщения об ошибке, возникающей при попытке открыть несуществующий файл.

После возникновения ошибки программист может либо прервать выполнение программы, для этого надо из меню Run выбрать команду Program Reset, либо продолжить ее выполнение, например, по шагам (для этого из меню Run надо выбрать команду Step), наблюдая результат выполнения каждой инструкции.

Рис. 13.1. Сообщение об ошибке при запуске программы из Delphi 

Если программа запушена из Windows, то при возникновении ошибки на экране также появляется сообщение об ошибке, но тип ошибки (исключения) в сообщении не указывается (рис. 13.2). После щелчка на кнопке ОК программа, в которой проявилась ошибка, продолжает (если сможет) работу.

Рис. 13.2. Сообщение об ошибке при запуске программы из Windows

 

С алгоритмическими ошибками дело обстоит иначе. Компиляция программы, в которой есть алгоритмическая ошибка, завершается успешно. При пробных запусках программа ведет себя нормально, однако при анализе результата выясняется, что он неверный. Для того чтобы устранить алгоритмическую ошибку, приходится анализировать алгоритм, вручную «прокручивать» его выполнение.

Помоги проекту! Расскажи друзьям об этом сайте:

  • 60
  • 1
  • 2
  • 3
  • 4
  • 5


1


Отладка программы


2


Классификация ошибок 1.синтаксические; 2. ошибки времени выполнения; 3.алгоритмические. Синтаксические ошибки, обнаруживает компилятор, а программисту остается только внести изменения в текст программы и выполнить повторную компиляцию.


3


Ошибки времени выполнения, (исключения – exception) Они обычно проявляются уже при первых запусках программы и во время тестирования. При возникновении ошибки в программе, запущенной из Delphi, среда разработки прерывает работу программы, и на экране появляется диалоговое окно, которое содержит сообщение об ошибке и информацию о типе (классе) ошибки. После возникновения ошибки программист может – либо прервать выполнение программы, ( Run — Program Reset), – либо продолжить ее выполнение, например, по шагам (Run — Step), наблюдая результат выполнения каждой инструкции.


4


Отладчик — мощное средство поиска и устранения ошибок в программе Отладчик позволяет – выполнять трассировку программы, – наблюдать значения переменных, – контролировать выводимые программой данные.


5


Трассировка программы В случае неправильной работы программы необходимо видеть реальный порядок выполнения инструкций. Трассировка это процесс выполнения программы по шагам (step-by-step), инструкция за инструкцией. Во время трассировки программист дает команду: выполнить очередную инструкцию программы.


6


2 режима трассировки Step over Режим трассировки без захода в процедуру выполняет трассировку только главной процедуры, при этом трассировка подпрограмм не выполняется, вся подпрограмма выполняется за один шаг. Trace into В режиме трассировки с заходом в процедуру выполняется трассировка всей программы, т. е. по шагам выполняется не только главная программа, но и все подпрограммы.


7


Как начать трассировку Из меню Run выбрать команду Step over или Trace into. В результате в окне редактора кода будет выделена первая инструкция программы Затем выбираем Step over (F8)или Trace into(F7) После выполнения инструкции будет выделена следующая. Таким образом, выбирая нужную команду из меню Run, можно выполнить трассировку программы Если нужна трассировка части программы следует 1. установить курсор на инструкцию программы, с которой надо начать трассировку, 2. из меню Run выбрать команду Run to cursor (F4). 3. нажимая клавишу или клавишу, выполнить трассировку нужного фрагмента программы. Завершить трассировку и продолжить выполнение программы в реальном темпе — из меню Run выбрать команду Run.


8


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


9


Добавление точки останова 1. из меню Run выбрать команду Add Breakpoint 2. затем из меню следующего уровня команду Source Breakpoint. Информация о добавляемой точке останова – в диалоговом окне Add Source Breakpoint Filename содержит имя файла программы Line number номер строки программы, в которую добавляется точка останова. После щелчка на кнопке ОК точка останова добавляется в программу, и строка, в которой находится точка останова, помечается красной точкой и выделяется цветом. Точку останова можно добавить, щелкнув мышью на синей точке, помечающей ту инструкцию программы, перед которой надо поместить точку останова (если в программе нет ошибок, то компилятор помечает выполняемые инструкции программы синими точками).


10


Условия для точки останова Если для точки останова задано условие, то программа приостанавливает свою работу только в том случае, если выражение, находящееся в поле Condition, истинно (его значение равно TRUE). можно задать количество пропусков данной точки. Если во время добавления в программу точки останова в поле Pass count (Число пропусков) диалогового окна Add Source Breakpoint записать отличное от нуля число, то программа приостановит свою работу в этой точке только после того, как инструкция, находящаяся в строке, помеченной точкой останова, будет выполнена указанное число раз.


11


Изменение характеристик точки останова Для этого надо из меню View выбрать команду Debug Windows, затем из меню следующего уровня команду Breakpoints. В открывшемся диалоговом окне Breakpoint List щелкнуть правой кнопкой мыши в строке, содержащей информацию о нужной точке останова, и в появившемся контекстном меню выбрать команду Properties. В результате открывается диалоговое окно Source Breakpoint Properties, в котором можно изменить характеристики точки останова, например, изменить условие (содержимое поля Condition) остановки программы в данной точке. Используя это же контекстное меню, можно быстро перейти к инструкции, в которой находится точка останова; для этого надо выбрать команду Edit Source.


12


Удаление точки останова в диалоговом окне Breakpoint List щелкнуть правой кнопкой мыши в строке, содержащей информацию о точке, которую надо удалить, и в появившемся контекстном меню выбрать команду Delete. Или в окне редактора кода щелкнуть мышью на красной точке, помечающей строку, в которой находится точка останова.


13


Наблюдение значений переменных Для того чтобы во время выполнения программы по шагам иметь возможность контролировать значение переменной, нужно добавить имя этой переменной в список наблюдаемых элементов (Watch List). Для этого надо из меню Run выбрать команду Add Watch и в поле Expression появившегося диалогового окна Watch Properties ввести имя переменной. В результате в список Watch List, будет добавлен новый элемент. Так как переменные программы существуют (и, следовательно, доступны) только во время выполнения программы, то после имени переменной выводится сообщение: process not accessible (процесс недоступен).


14


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


15


Завершить пошаговое выполнение Чтобы завершить процесс пошагового выполнения программы, нужно из меню Run выбрать команду Program Reset.

Logo Море(!) аналитической информации!

Глава 6. Отладка в интегрированной среде

             Интегрированная интерактивная  среда   разработки   программ
        Borland Pascal  (IDE)  включает  в себя ряд средств,  облегчающих
        разработку программ: автоматическое управление проектами, средств
        обеспечения модульной  структуры программы,  быструю компиляцию и
        простые в использовании оверлеи.  Но несмотря  на  все  это  ваша
        программа все  равно  может содержать ошибки,  что не позволит ей
        корректно работать.

             IDE для DOS Borland Pascal предоставляет вам  инструменталь-
        ные средства  для отладки программ,  то есть поиска и исправления
        ошибок. В этой главе описываются инструментальные средства и про-
        цедуры отладки программы в интегрированной среде, включая следую-
        щие темы:

             * обзор ошибок и методов отладки;

             * управление выполнением программы;

             * проверка значений;

             * остановки выполнения программы.

             Данная глава посвящена встроенному отладчику  IDE  для  DOS.
        Все описанные  процедуры применимы также к Турбо отладчику (Turbo
        Debugger) и Турбо отладчику для Windows,  хотя имена меню и нажи-
        маемые клавиши в них могут отличаться.



Что такое отладка?

Отладка - это процесс поиска и исправления ошибок в програм- ме, препятствующих корректной работе программы. Перед тем как уг- лубиться в специфические средства IDE Borland Pascal, которые по- могают при отладке, дадим краткое описание видов ошибок, которые вы можете наблюдать, и различного рода операций, которые вы будет использовать для их поиска.

Какие существуют виды ошибок?

Существует три основных типа ошибок: ошибки этапа компиля- ции, ошибки этапа выполнения и логические ошибки. Если вы уже хо- рошо знакомы с этими понятиями, то можете пропустить следующий раздел до методов отладки. Ошибки этапа компиляции Ошибки этапа компиляции или синтаксические ошибки происхо- дят, когда ваш исходный код нарушает правила синтаксиса Паскаля. Borland Pascal на может скомпилировать вашу программу, пока она не будет содержать допустимые операторы Паскаля. Когда компилятор встречает оператор, который он не может распознать, соответствую- щий файл выводится в окне редактирования, курсор позиционируется на то место, которое не понял компилятор, и выводится сообщение об ошибке. Компилятор, работающий в режиме командной строки, также дает вам некоторую информацию. Когда он находит синтаксическую ошибку, то выводит содержащую ошибку строку с номером этой строки и сооб- щением об ошибке. Наиболее общей причиной ошибок этапа компиляции являются ошибки набора (опечатки), пропущенные точки с запятой, ссылки на неописанные переменные, передача неверного числа (или типа) пара- метров процедуры или функции и присваивание переменной значений неверного типа. После исправления ошибки вы можете выполнить компиляцию за- ново. После устранения в программе всех синтаксических ошибок и ее успешной компиляции программа будет готова к выполнению и по- иску ошибок этапа выполнения и логических ошибок. Ошибки этапа выполнения Ошибки этапа выполнения или семантические ошибки происходят, когда вы компилируете полную программу, которая при ее выполнении делает что-то недопустимое. То есть, программа содержит допусти- мые операторы Паскаля, но при выполнении операторов что-то проис- ходит неверно. Например, ваша программа может пытаться открыть для ввода несуществующий файл или выполнить деление на ноль. Когда программа Borland Pascal обнаруживает такую ошибку, она завершает выполнение и выводит сообщение следующего вида: Run-time error ## at seg:ofs Если вы выполняете программу из IDE, Borland Pascal автома- тически находит вызвавший ошибку оператор (как в случае синтакси- ческих ошибок). Если вы выполняете программу вне IDE, то вы може- те запустить IDE и, чтобы найти вызвавший ошибку оператор, ис- пользовать команду Search|Find Error, которая дает вам адрес сег- мента и смещения (seg:ofs). Если вы используете компилятор ко- мандной строки, то можете для поиска ошибки использовать параметр /F. Логические ошибки Логические ошибки - это ошибки проектирования и реализации программы. То есть, ваши операторы допустимы и что-то делают, но не то, что вы предполагали. Эти ошибки часто трудно отследить, поскольку IDE не может найти их автоматически, как синтаксические и семантические ошибки. К счастью, IDE включает в себя средства отладки, помогающие вам найти логические ошибки. Логические ошибки приводят к некорректному или непредвиден- ному значению переменных, неправильному виду графических изобра- жений или невыполнению кода, когда это ожидается. В остальной части этой главы обсуждаются методы отслеживания этих логических ошибок.

Методы отладки

Иногда, когда программа делает что-то непредвиденная, причи- на достаточно очевидна, и вы можете быстро исправить код програм- мы. Но другие ошибки более трудноуловимы и вызываются взаимодейс- твие различных частей программы. В этих случаях лучше всего оста- новить вашу программу в заданной точке, пройти ее шаг за шагом и просмотреть состояние переменных и выражений. Такое управляемое выполнение - ключевой элемент отладки. В данном разделе описываются различные возможности отладки в IDE для DOS Borland Pascal. Выполнение по шагам и трассировка Команды выполнения по шагам Step Over и трассировки Trace Into меню выполнения Run дают вам возможность построчного выпол- нения программы. Единственное отличие выполнения по шагам и трас- сировки состоит в том, как они работают с вызовами процедур и функций. Выполнение по шагам вызова процедуры или функции интерп- ретирует вызов как простой оператор и после завершения подпрог- раммы возвращает управление на следующую строку. Трассировка подпрограммы загружает код этой подпрограммы и продолжает ее построчное выполнение. Остановка выполнения Существует два способа сообщить IDE, что программу нужно вы- полнить до определенной точки, а затем остановить. Первый и прос- тейший способ состоит в том, чтобы найти позицию в программе, где вы хотите остановиться, затем выбрать в меню Run команду Go to Cursor (Выполнение до позиции курсора). Ваша программа выполняет- ся как обычно, пока не достигнет оператора, где она должна оста- новиться. В этой точке вы можете проверить значения и продолжать выполнение непрерывно или по шагам. Второй способ состоит в том, чтобы остановить в определенной заданной точке вашу программу. Эта точка называется точкой оста- нова. Когда вы выполняете программу, она останавливается перед выполнением оператора в точке останова. Точки останова - это бо- лее гибкий механизм, чем использование метода выполнения до пози- ции курсора (Go to Cursor), поскольку в программе вы можете уста- новить несколько точек останова. Отслеживание и модификация При выполнении программы по шагам вы можете наблюдать ее вы- вод несколькими способами. Первый состоит в переключении в случае необходимости экранов. При втором способе используется второй мо- нитор. В-третьих, для вывода программы вы можете открыть окно в IDE для DOS. Кроме того, чтобы показать вывод программы, встроенный от- ладчик позволяет вам просматривать значения переменных, выражений и структур данных. С помощью команды Wathes в меню Debug в окне просмотра Watches вы можете добавлять или удалять отслеживаемые элементы. В этом диалоговом окне вы можете проверять переменные и выражения и изменять значения любых переменных, включая строки, указатели, элементы массива и поля записей, что позволяет вам проверять реакцию программы на различные условия. Поиск Если вам нужно найти в программе описания процедуры или функции, либо определения объекта, это легко можно сделать с по- мощью средства просмотра объектов ObjectBrowser. С помощью меню Search и выбора команд Objects, Globals, Units или Symbols выбе- рите соответствующее окно просмотра. См. Главу 4 ("Программирова- ние в интегрированной среде для DOS"), где о просмотре кода расс- казывается более подробно.

Генерация отладочной информации

Перед отладкой программы вам нужно указать компьютеру, что нужно сообщить компилятору на необходимость генерации некоторой дополнительной информации, благодаря которой он сможет отслежи- вать, какие строки исходного кода соответствуют отдельным частям выполняемой программы. Эта дополнительная информация называется отладочной информацией. Вы можете включить эту информации, выбрав соответствующий параметр (кнопку с независимой фиксацией) диалогового окна Compiler Options интегрированной среды (команда Options|Compiler) или включив в код программы соответствующую ди- рективу компилятора. Когда вы компилируете программу Borland Pascal, компилятор всегда сохраняет список используемых идентификаторов, который на- зывается таблицей идентификаторов. В этом списке отслеживаются имена всех переменных, констант, типов, процедур и функций. Для целей отладки там сохраняются также номера строк исходных файлов, где встречаются все эти идентификаторы. Выбрав в диалоговом окне Compiler Options параметр Debug Information (Отладочная информа- ция) или задав директиву компилятора $D+, вы указываете компиля- тору, что в таблицу идентификаторов нужно добавить информацию о номерах строк. Встроенная и автономная отладка В диалоговом окне параметров отладчика Debugger Options (Options|Debugger) вы можете сообщить компилятору, нужно ли гене- рировать отладочную информацию для использования встроенного или автономного отладчика (такого как Turbo Debugger), или для обоих. Если вы хотите использовать встроенный отладчик, то нужно выбрать параметр Integrated (который устанавливается по умолчанию). Информация в модулях Если вы пишете большую программу, которая использует модули, и отладочная информация получается слишком объемной, вы можете сократить объем этой информации для отдельных модулей, используя в них директиву компилятора $L- или отменив в диалоговом окне Compiler Options параметр Local Symbols (Информация о локальных идентификаторах). Если вы выключите для модуля генерацию информации о локаль- ных идентификаторах, то из отладочной информации для этого модуля исключаются все идентификаторы, описанные в секции реализации мо- дуля. Для всех идентификаторов в интерфейсной секции будет гене- рироваться информацию для всех идентификаторов, так что вы сможе- те использовать средства отладки.

Управление выполнением

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

Что такое шаг?

Когда вы отлаживаете программу, наименьшим выполняемым эле- ментом является строка. Этот означает, что вы можете управлять отладкой до уровня отдельной строки исходного кода программы. По- этому, если на одной строке программы содержится несколько опера- торов Паскаля, вы не сможете отладить эти операторы индивидуаль- но. С другой стороны, с целью отладки вы можете разбить оператор на несколько строк, которые будут выполняться за один шаг. Все выполнение в отладчике, включая выполнение по шагам, трассировку и останов, основывается на строках. Подсвечивая стро- ку, встроенный отладчик всегда сообщает вам, какую строку вы вы- полняете следующей (строка выполнения). Строка выполнения выво- дится цветом, отличным от нормального цвета. Благодаря этому вы можете легко видеть, где находитесь.

Выполнение программы по шагам

Выполнение по шагам - это простейший способ выполнения прог- раммы по элементарным фрагментам. Выбор команды Run|Step Over или нажатие клавиши F8 вызывает выполнение отладчиком всего кода в операторе, указанном строкой выполнения, включая любые вызываемые на ней процедуры или функции, пока управление не вернется обратно к вам. После этого строка выполнения указывает следующий выполня- емый оператор. Возьмем, например, следующий пример программы: program StepTest; function Negate(X: Integer): Integer; begin Negate := -X; end; var I: Integer; begin for I := 1 to 10 do Writeln(Negate(I)); end. Пример 6.1 Простая программа, выполняемая по шагам. Если в окне редактирования вы выведите StepTest и нажмете клавишу F8, то строка выполнения перемещается на оператор begin в начале основного цикла, поскольку это первое, что выполняется в программе. Второе нажатие клавиши F8 выполняет begin и перемещает строку выполнения вниз до оператора for на следующей строке. Пос- ле этого нажатие F8 вызывает выполнение всего цикла for; на экран пользователя выводятся числа от -1 до -10, а строка выполнения перемещается к end. Хотя функция Negate вызывается 10 раз, строка выполнения ни- когда на нее не перемещается. Выполнение по шагам позволяет от- ладчику не показывать детали любых вызовов для отдельной строки. Выполнение по шагам вызывает выполнение всего цикла for сразу, поэтому вы не сможете видеть изменения в ходе выполнения цикла. Если вы хотите видеть подробности цикла, внесите в пример следую- щее простое изменение. begin for I := 1 to 10 do Writeln(Negate(I)); end. Пример 6.2 Изменение формата кода для лучшего выполнения по шагам. Поскольку оператор Паскаля может занимать несколько строк, такая программа будет в точности эквивалентна предыдущей версии, а генерируемый код будет идентичен. Но поскольку оператор Writeln теперь находится на отдельной строке, отладчик может интерпрети- ровать его отдельно. Если теперь вы будете нажимать клавишу F8, то увидите, что строка выполнения будет при выполнении цикла 10 раз возвращаться на Writeln.

Трассировка программы

Трассировка программы во многом аналогичная ее выполнению по шагам. Единственное исключение состоит в том, что когда встреча- ется оператор вызова процедуры или функции, при трассировке эти процедуры и функции также выполняются по шагам, а при простом вы- полнении по шагам управление возвращается вам после завершения выполнения подпрограммы. Например, чтобы выполнить трассировку кода в Примере 6.1, загрузите файл, затем выберите команду Run|Trace Into или нажмите клавишу F7. Когда вы в первый раз делаете это, управление переме- щается на оператор begin основной программы. Повторное нажатие F7 снова перемещает строку управления на оператор for. После этого нажатие клавиши F7 трассирует вызов функции Negate - строка вы- полнения перемещается на оператор begin в блоке функции. Если вы продолжаете нажимать F7, строка выполнения перемещается по функ- ции, а затем, когда вы дойдете до оператора end, возвращается к оператору вызова. Формат вашей программы влияет на поведение строки выполнения при трассировке, хотя и не в такой степени как при пошаговом вы- полнении. Если код сформатирован как в Примере 6.1, то трассиров- ка оператора for приводит к выполнению 10 раз функции Negate. Ес- ли вы разобъете оператор for на две строки, как в Примере 6.2, то трассировка оператора end функции возвращает строку выполнения ту строку основной программы, которая будет выполняться следующей. Первые девять раз это снова будет вызов функции. В десятый раз строка выполнения перемещается на оператор end программы.

Трассировка или выполнение по шагам?

Пошаговое выполнение или трассировка выполняет одно и то же действие, кроме того случая, когда строка выполнения находится под строкой вызова процедуры или функции, или когда вы выполняете оператор begin в начале программы или модуля, который использует другие модули. Выполнение begin в блоке begin..end основной программы вызы- вает код инициализации для любого используемого в программе моду- ля в том порядке, который указывается в операторе uses программы. Аналогично, выполнение оператора begin в начале секции инициали- зации вызывает код инициализации для любых модулей, используемых в данном модуле. Выполнение по шагам и трассировка работает в этих случаях как и можно ожидать - пошаговое выполнение begin вы- полняет всю инициализацию, возвращая управление на следующий опе- ратор только после того, как все будет завершено; при трассировке выполняется трассировка кода инициализации. Примечание: О модулях и их секциях инициализации расс- казывается в Главе 7 "Модули Borland Pascal". Пошаговое выполнение и трассировка методов объектов Если вы используете в своей программе объекты, отладчик ин- терпретирует свои методы аналогично тому, как он интерпретирует обычные процедуры и функции. Пошаговое выполнение метода интерп- ретирует метод как один шаг, возвращая управление к отладчику после того как метод завершает выполнение. Трассировка метода загружает и выводит на экран код метода и трассирует его операто- ры. Пошаговое выполнение и трассировка внешнего кода Если вы выполняете в программе компоновку с внешним кодом, используя для этого директиву компилятора {$L имя_файла}, то если компонуемый файл .OBJ содержит отладочную информацию, вы можете трассировать этот код или выполнять его по шагам. Borland Pascal ничего не знает об отлаживаемом вами коде в этих модулях, но он будет показывать вам соответствующие строки в исходном коде. Примечание: Требования к внешнему коду поясняются в Главе 25 "Руководства по языку". Вы можете отлаживать внешний код, написанный на любом языке, включая Си, С++ и ассемблер. Если код отвечает требованиям для внешней компоновки и содержит полную стандартную отладочную ин- формацию, интегрированная среда отладчика может выполнять его по шагам или трассировать.

Выполнение больших фрагментов

Иногда, конечно, нежелательно выполнять по шагам всю прог- рамму только для того, чтобы добраться до того места, где возни- кает проблема. Отладчик дает вам возможность выполнять сразу большой фрагмент программы до той точки, где вы хотите начать вы- полнение по шагам. Чтобы задать в программе точку, до которой вы хотите ее вы- полнить, а затем остановиться, используйте команду Run|Go To Cursor (Выполнение|Выполнение до курсора) или клавишу F4. (Этим вы сообщите отладчику, что не хотите выполнять программу по ша- гам, пока не достигнете заданной точки.) Позиционируйте курсор на той строке, где вы хотите возобновить управление отладкой, затем нажмите клавишу F4. Заметим, что вы можете сделать это как в на- чале сеанса отладки, так и когда уже выполните часть программы по шагам или протрассируете.

Поиск нужного места

IDE предусматривает два способа поиска в программе заданного места. Простейший способ предоставляет команда Find Procedure ме- ню Search. Команда Find Procedure (Поиск процедуры) запрашивает у вас имя процедуры или функции, затем находит соответствующую строку в файле, где определяется эта подпрограмма. Этот подход полезно использовать при редактировании, но его можно комбиниро- вать с возможностью выполнения программы до определенной точки, чтобы пройти программу до той части кода, которую вы хотите отла- дить. Возврат Иногда в ходе отладки полезно узнать, как вы попали в данную часть кода. Окно Call Stack (Стек вызова) показывает вам последо- вательность вызовов процедур или функций, которые привели к теку- щему состоянию (глубиной до 128 уровней). Для вывода окна Call Stack используйте команду Debug|Call Stack. Окно Call Stack особенно полезно использовать, если вы слу- чайно начали трассировку кода, который хотели бы выполнить за один шаг. В стеке вызовов вы можете найти тот вызов, который на- чали трассировать по ошибке, затем выбрать команду Run to Cursor, чтобы выполнить за один шаг остальную часть вызова.

Повторное выполнение

В ходе сеанса отладки иногда желательно начать все сначала. Выберите команду Run|Reset Program или нажмите клавиши Ctrl+F2. Это приведет к полному сбросу, так что выполнение по шагам, или трассировка начнется в начале основной программы.

Отслеживание вывода программы

При выполнении программы по шагам часто полезно просмотреть вывод программы, называемый экраном пользователя. В прикладной программе Windows это достаточно просто, так как программа уже выполняется в отдельном окне. Однако в DOS это не так легко. К счастью, Borland Pascal предоставляет вам несколько способов просмотра экрана пользователя.

Переключение экранов

В любой момент сеанса отладки вы можете выполнять переключе- ние экрана IDE и экрана пользователя. Чтобы вывести экран пользо- вателя, нажмите клавиши Alt+F5. Чтобы вернуться в IDE, нажмите любую клавишу или щелкните "мышью". При выполнении программы отладчик также может переключать экраны автоматически. Управлять характером переключения экранов вы можете с помощью параметров Display Swapping (Переключение эк- рана) диалогового окна Debugger. По умолчанию задано эффективное переключение. Это означает, что экран пользователя выводится только в том случае, если выполняемый оператор выводит информацию на экран или вызывает процедуру (даже если эта процедура ничего на экран не выводит). После завершения вывода экран переключается обратно в IDE. Вы можете также сообщить отладчику, что переключать экран нужно на каждой строке, независимо от вывода, или не переключать их вовсе. Переключение экранов для каждой строки полезно исполь- зовать, если ваша программа посылает информацию непосредственно на экран, что может затереть содержимое экрана IDE.

Окно Output

IDE для DOS предусматривает для экрана пользователя окно, которое называется окном вывода. Выбрав команду меню Debug| Output, вы можете открыть (вывести на переднем плане) активное окно, содержащее вывод программы. Настроить размер этого окна можно аналогично окну редактирования.

Использование двух мониторов

IDE предоставляет вам возможность использования для целей отладки второго монитора. Этот монитор должен быть монохромным дисплеем (поскольку использует память, отличную от цветного дисп- лея), и вам нужно будет запустить IDE с параметром /D. В режиме с двумя мониторами экран IDE выводится на монохромном экране, вывод вашей программы - на цветном экране, а переключение экранов не выполняется.

Просмотр значений

Выполнение программы по шагам или ее трассировка могут по- мочь вам найти ошибки в алгоритме программы, но обычно желательно также знать, что происходит на каждом шаге со значениями отдель- ных переменных. Например, при выполнении по шагам цикла for по- лезно знать значение переменной цикла. IDE Borland Pascal имеет два инструментальных средства для проверки содержимого переменных программы: окно Watches (Просмотр) и диалоговое окно Evaluate and Modify (Вычисление и модификация).

Что такое выражение?

Оба средства вычисление и просмотра работают на уровне выра- жений, поэтому важно определить, что считается выражением. Выра- жение состоит из констант, переменных и структур данных, скомби- нированных с помощью операций и большинства встроенных функций. Почти все, что вы можете использовать в правой части оператора присваивания, может также использоваться в качестве отладочного выражения. Точные спецификации показаны в Таблице 6.1. Элементы выражений отладчика Таблица 6.1 +--------------------------+------------------------------------+ | Элемент выражения | Допустимые значения | +--------------------------+------------------------------------| | Константы | Все допустимые типы: Boolean, Byte,| | | Char, перечислимый тип, Integer,| | | Longint, Real, Shortint, Word и| | | строковый тип. | +--------------------------+------------------------------------| | Переменные | Все типы, включая типы, определен-| | | ные пользователям. | | | | | целочисленный тип | Любое целочисленное выражение с пе-| | | ременными границами диапазона. | | | | | тип с плавающей точкой| Любые выражения с плавающей точкой| | | или целочисленные выражения; лишние| | | значащие цифры отбрасываются. | | | | | символьный тип | Любое символьное выражение, включая| | | печатаемые символы в одинарных ка-| | | вычках, целочисленные выражения,| | | тип которых приведен к типу Char, и| | | контанты ASCII (#xx). | | | | | булевский тип | True, False и все булевские выраже-| | | ния. | | | | | перечислимый тип | Любые совместимые перечислимые кон-| | | станты или целочисленные выражения| | | в рамках диапазона, тип которых| | | приведен к совместимому перечисли-| | | мому типу. | | | | | указатель | Любые совместимые указатели или вы-| | | ражения с приведенными к ним типа-| | | ми; функция Ptr с соответствующим| | | параметрами. | | | | | строковый тип | Любая строковая константа (текст в| | | одинарных кавычках); строковые пе-| | | ременные; строковые выражения, сос-| | | тоящие из конкатенированных строко-| | | вых констант и переменных. | | | | | множество | Любая множественная константа; лю-| | | бое выражение, совместимое с мно-| | | жественным типа, в котором исполь-| | | зуются операции +, - и *. | +--------------------------+------------------------------------| | Приведение типа | Соблюдаются стандартные правила| | | Паскаля. | +--------------------------+------------------------------------| | Операции | Все операции Borland Pascal. | +--------------------------+------------------------------------| | Встроенные функции | Все функции, допустимые в выражени-| | | ях-константах. | +--------------------------+------------------------------------| | Массивы | Массивы Borland Pascal - Mem, MemL,| | | MemW. | +--------------------------+------------------------------------+

Просмотр выражений

Если вы хотите отслеживать значение переменной или выражения при выполнении программы по шагам, то можете открыть окно прос- мотра Watches. Это окно IDE показывает переменные и их значения в каждый конкретный момент. Чтобы открыть окно Watches, выберите команду Window|Watch. IDE открывает активное окно Watches без активных записей. Если вы выберите переменную для просмотра, IDE автоматически открывает окно Watches (если вы этого еще не сделали). Добавление просматриваемого выражения Чтобы добавить в окно Watches переменную, выберите команду Debug|Watch|Add Watch или нажмите клавиши Ctrl+F7. Если окно Watches является активным окном, вы можете добавить выражение просмотра, нажав клавишу Ins. Отладчик открывает диалоговое окно, запрашивающее у вас тип просматриваемого выражения. По умолчанию выражением считается слово в позиции курсора в текущем окне ре- дактирования. Просматриваемые выражения, которые вы отслеживали ранее, сохраняются в списке протокола. Отслеживание текущего просматриваемого выражения Последнее добавленное или модифицированное просматриваемое выражение является текущим просматриваемым выражением, которое указывается выводимым слева от него символом жирной левой точки. Если окно Watches активно, вы можете также удалить текущее выра- жение, нажав клавишу Del или Ctrl+Y. Чтобы удалить все просматри- ваемые выражения, выберите команду Debug|Watch|Remove All Watches. Редактирование просматриваемых выражений Чтобы отредактировать просматриваемое выражение, нужно дваж- ды щелкнуть на этом выражении "мышью" или сделать это выражение текущим, затем нажать клавишу Enter или выбрать команду Debug| Watch|Edit Watch. Отладчик открывает диалоговое окно, аналогичное тому, которое используется для добавления просматриваемого выра- жения, которое позволяет вам отредактировать текущее выражение. При выборе командной кнопки OK или нажатии клавиши Enter отредак- тированное выражение заменяет оригинал. Форматирование просматриваемых выражений Окно Watches позволяет вам несколькими способами форматиро- вать просматриваемые выражения, добавляя запятую и один или более спецификаторов формата. Например, хотя целочисленные значения вы- водятся обычно в десятичном виде, указав после него ,H, вы можете задать вывод выражения в шестнадцатиричном формате. Допустимые спецификаторы формата и их действие перечисляются в Таблице 6.2.

Спецификаторы формата в выражениях отладчика

Таблица 6.2 +--------------+---------------------+--------------------------+ | Символ | Тип, на который | Функция | | | он влияет | | +--------------+---------------------+--------------------------| | $, H или X | целочисленные типы | Шестнадцатиричный. Выво-| | | | дит целочисленные значе-| | | | ния в префиксом $, вклю-| | | | чая те, которые содержат-| | | | ся в структуре данных. | +--------------+---------------------+--------------------------| | C | Char, строковые | Символьный. Выводит спе-| | | типы | циальные символы для ко-| | | | дов ASCII 0..31. По умол-| | | | чанию такие символы выво-| | | | дятся в виде значений| | | | #xx. | +--------------+---------------------+--------------------------| | D | целочисленные | Десятичный. Выводят цело-| | | типы | численные значения в де-| | | | сятичном виде (включая| | | | те, которые содержатся в| | | | структурах данных). | +--------------+---------------------+--------------------------| | Fn | с плавающей точкой | С плавающей точкой. Выво-| | | | дит n значащих цифр, где| | | | n лежит в диапазоне 2..18| | | | (по умолчанию - 11). | +--------------+---------------------+--------------------------| | nM | все | Дамп памяти. Выводит n| | | | байт памяти, начиная с| | | | адреса, указываемого вы-| | | | ражением. Если n не зада-| | | | но, то по умолчанию оно| | | | равно значению размера в| | | | байтах типа переменной. | +--------------+---------------------+--------------------------| | P | указатели | Указатель. Выводит указа-| | | | тели по адресу сегм:смещ| | | | (на не Ptr(сегм:смещ),| | | | как это делается по умол-| | | | чанию. | +--------------+---------------------+--------------------------| | R | записи, объекты | Запись. Выводит имена по-| | | | лей, например, (X:1;| | | | Y:10; Z:5) вместо (1, 10,| | | | 5). | +--------------+---------------------+--------------------------| | S | Char, строки | Строки. Выводит символы| | | | ASCII 0..31 в виде #xx.| | | | Использует только для мо-| | | | дификации дампов памяти| | | | (см. выше nM). | +--------------+---------------------+--------------------------+

Вычисление и модификация

Кроме добавления просматриваемых выражений при выполнении программы, отладчик имеет средство, позволяющее вам в любой мо- мент вычислять выражения и изменять на этапе выполнения значения переменных. Вычисление выражений Чтобы вычислить выражение, выберите команду Debug|Evaluate/ Modify или нажмите клавиши Ctrl+F4. Отладчик выводит диалоговое окно Evaluate and Modify (Вычисление и модификация). По умолчанию слово в позиции курсора в текущем окне редактирования выводится подсвеченным в поле Expression (Выражение). Вы можете отредакти- ровать это выражение, набрать другое выражение или выбрать вычис- ляемое вами ранее выражение из списка протокола. Когда вы нажимаете Enter или щелкаете "мышью" на командной кнопке Evaluate, текущее значение выражения в поле Expression по- казывается в поле Result. Допустимые выражения для вычисления подчиняются тем же пра- вилам, что и выражения для сравнения. Для вывода результатов вы- числения выражения действую спецификаторы формата, перечисленные в Таблице 6.2. Модификация переменных Во время отладки с помощью диалогового окна Evaluate and Modify вы можете изменить значение переменной. Введите переменную в поле Expression, затем в поле New Value наберите новое значение. При изменении значений переменных следует иметь в виду сле- дующее: * Вы можете изменять только отдельные переменные или элемен- ты массивов или записей, но не сами массивы и записи. * Выражения в поле New Value должны отвечать ограничениям для выражений, перечисленных в Таблице 6.1. * Выражение в поле New Value (Новое значение) должно в ре- зультате вычисления давать результат, совместимый по прис- ваиванию с переменной, которой вы хотите ее присвоить. Здесь можно руководствоваться следующим правилом: если присваивание дает при компиляции ошибку, то оно не являет- ся допустимым значением модификации.

Использование точек останова

Borland Pascal дает вам возможность устанавливать в свое программе для целей отладки точки останова. Точка останова - это обозначенная в коде программы позиция, в которой вы хотите прек- ратить выполнение программы и вернуть выполнение отладчику. В этом смысле точка останова работает аналогично команде Go to Cursor, при которой программа выполняется обычным путем до дости- жения определенной точки. Основное различие состоит в том, что вы можете задать несколько точке останова и точки останова, которые будут срабатывать не при каждом их достижении.

Задание точек останова

Чтобы установить в своем в своем коде точку останова, пере- местите курсор на той строке, где вы хотите остановиться. Строка должна содержать выполняемый код и не может быть комментарием, описанием или пустой строкой. Выбор команды Toggle Breakpoint в локальном меню окна редактирования или нажатие клавиш Ctrl+F8 ус- танавливает на строке точку останова, которая обозначается подс- веткой всей строки. Теперь при выполнении программы из IDE она будет останавли- ваться при достижении данной строки, но перед ее выполнением. Строка, содержащая точку останова, выводится при этом в окне ре- дактирования как строка выполнения. В этот момент вы можете вы- полнить любые другие действия по отладке (выполнение программы по шагам, трассировку, просмотр и вычисление).

Отмена точке останова

Чтобы отменить точку останова, поместите курсор на содержа- щую ее строку и выберите в локальном меню окна редактирования ко- манду Toggle Breakpoint или нажмите клавиши Ctrl+F8.

Модификация точек останова

В процессе сеанса отладки IDE отслеживает все точки остано- ва. Вместо того, чтобы шарить по исходному коду в поиске точек останова, она обслуживать точки останова в одном диалоговом окне Breakpoints. Для вывода диалогового окна Breakpoints выберите ко- манду View|Breakpoints. В этом диалоговом окне вы можете устанав- ливать, удалять, редактировать и просматривать свои точки остано- ва. Командные кнопки диалогового окна Breakpoints работают сле- дующим образом: * Чтобы добавить новую точку останова, подсветите пустую строку в списке и выберите командную кнопку Edit. * Чтобы отменить точку останова, подсветите ее и выберите кнопку Clear. * Чтобы модифицировать существующую точку останова, подсве- тите ее и выберите командную кнопку Edit. * Чтобы найти в своем исходном коде точку останова, подсве- тите ее и выберите кнопку View. * Чтобы удалить все точки останова, выберите командную кноп- ку Clear All.

Создание условный точек останова

Точки останова, добавленные командой Toggle Breakpoint, яв- ляются безусловными: когда вы попадаете на эту строку, отладчик в любом случае останавливает программу. Если вы редактируете новую или существующую точку останова, то у вас есть две дополнительные возможности - с помощью параметров диалогового окна Edit Breakpoint вы можете создать условные точки останова. В этих точ- ках останова вы можете задать два вида условий: счетчик проходов и логические условия. Подсчет числа проходов Задание для точки останова счетчика проходов сообщает отлад- чику, что останавливать программу нужно не при каждом достижении точки останова, а только на n-ый раз. То есть, если счетчик про- ходов равен 3, то отладчик останавливает программу только при третьем достижении данной точки останова. Проверка условий В качестве условия для точки останова можно также задать вы- ражение типа Boolean. Например, вы можете проверить, попадает ли переменная в заданный диапазон, или установлен ли некоторый флаг. В таких условиях для точек останова вы можете задавать любые бу- левские выражения, подчиняющиеся правилам Таблицы 6.1.

Прерывание программы без точек останова

Даже если вы не установите точек останова, то все равно смо- жете выйти в отладчик при выполнении программы из IDE. В любой момент работа программы нажмите клавиши Ctrl+Break. Отладчик на- ходит позицию в исходном коде, где вы прервали программу. Как и в случае обычно точки останова вы можете затем выполнить программу по шагам, трассировать ее, отследить или вычислить выражения.

                              Назад | Содержание | Вперед


Обратная связь
Информация для авторов

Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum

Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее…

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Откуда происходит название эпохи возрождения а термин возрождение это ошибка культурологов
  • Откуда произошло слово ошибка