Если отладка это процесс удаления ошибок в программе то программирование это

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

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

Особенности
процесса тестирования программы состоят
в том, что:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3. Ошибки реализации алгоритма

Под
эту категорию подпадают все ошибки,
вызванные неверным программированием
при верном алгоритме. Этот тип ошибок,
по-видимому, является самым распространенным
и наиболее трудно классифицируемым.

4. Ошибки алгоритма

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

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

5. Ошибки метода

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

Заповеди отладки
программного средства

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

Ниже
приводятся рекомендации по организации
отладки в форме заповедей.

Заповедь
1. Считайте
тестирование ключевой задачей разработки
ПС, поручайте его самым квалифицированным
и одаренным программистам; нежелательно
тестировать свою собственную программу.

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

Заповедь
2. Хорош тот
тест, для которого высока вероятность
обнаружить ошибку, а не тот, который
демонстрирует правильную работу
программы.

Заповедь
3. Готовьте
тесты как для правильных, так и для
неправильных данных.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Методы и средства получения дополнительной информации

Для получения дополнительной информации об ошибке можно выполнить добавочные тесты или использовать специальные методы и средства:

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

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

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

Интегрированные средства отладки. Большинство современных сред программирования (Delphi, Builder C++, Visual Studio и т. д.) включают средства отладки, которые обеспечивают максимально эффективную отладку. Они позволяют:

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

Отладка с использованием независимых отладчиков.

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

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

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

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

Читать также:  Ошибка при запуске программы loader

2 этап — локализация ошибки — определение конкретного фрагмента, при выполнении которого произошло отклонение от предполагаемого вычислительного процесса. Локализация может выполняться:

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

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

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

4 этап — исправление ошибки — внесение соответствующих изменений во все операторы, совместное выполнение которых привело к ошибке.

5 этап — повторное тестирование — повторение всех тестов с начала, так как при исправлении обнаруженных ошибок часто вносят в программу новые.

Следует иметь в виду, что процесс отладки можно существенно упростить, если следовать основным рекомендациям структурного подхода к программированию:

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

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

Интересно
происхождение английского термина
debug,
буквально означающего «обезжучивание»
(англ. bug
означает «жук»). В 40-х гг. ХХ века во
флоте США эксплуатировался компьютер
Mark-1.
Однажды машина вышла из строя по причине
попадания самого настоящего жука в
контакты одного из многих тысяч реле.
Математик Г.М. Хоппер, разрабатывавшая
программы для Mark-1,
записала в журнале «Реле №70. Произведено
обезжучивание». С тех пор термин debug
прижился для обозначения процесса
отладки.

Еще
сравнительно недавно отладка программы
была весьма трудоемким и утомительным
делом. Работа с компиляторами таких
языков, как C,
Fortran
или Clipper
в ОС MS
DOS
выглядела следующим образом. Текст
программы набирался в любом текстовом
редакторе – от Word
до блокнота. Далее запускался компилятор,
которому на вход подавался файл с
программой. Если компиляция проходила
успешно, компилятор создавал так
называемый объектный файл. Затем
запускался линкер
– программа, объединяющая код стандартных
библиотек и код в объектном файле в
окончательный exe-файл.
Наконец, полученный exe-файл
запускался на выполнение. Если в нем
обнаруживалась ошибка, весь процесс
надо было повторять заново.

Резкому
повышению производительности труда
программистов способствовало появление
интегрированных сред программирования
(IDE,
Integrated
Development
Environment).
Delphi как раз и является такой средой. IDE
объединяет редактор текста, компилятор,
линкер, отладчик (рис. 13.1).

Рис.
2.1
— Структура IDE.

Самая
интересная для нас часть IDE
– отладчик
(debugger).
Он позволяет выполнять следующие
действия:

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

Как
это возможно? Ведь мы знаем, что не
существует способа превратить exe-файл
обратно в программу на Паскале. Дело в
том, что компилятор со встроенным
отладчиком записывает в EXE-файл «лишнюю»
информацию – имена переменных, ссылки
на строки в исходной программе и т.д.
После окончательной отладки следует
отключить генерацию отладочной информации
и откомпилировать «чистую» программу.
Если об этом забыть то, во-первых,
бесполезно возрастет размер exe-файла,
а во-вторых, злобным хакерам будет очень
легко вскрыть разнообразные защиты,
которые автор так долго и старательно
создавал.

Режимы
компиляции в пункте меню
ProjectàOptionsàCompiler
().

Если отладка это процесс удаления ошибок в программе то программирование это

Рис.
2.2
— Управление режимами компиляции в
Delphi.

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

Точка
прерывания ставится на строчку программы.
В Delphi
это делается клавишей F5.
Строка, в которой установлена точка
прерывания, в редакторе помечается
красным цветом (Рис. 2 .3).

Бесполезно
ставить точку останова на операторы
END,
VAR, CONST, TYPE, FUNCTION, PROCEDURE, UNIT
– они не являются исполняемыми.
Разумеется, не сработает и точка
прерывания, стоящая внутри процедуры,
если эта процедура ниоткуда не вызывается
на выполнение.

Как
только точка прерывания достигнута,
можно просмотреть текущие значения
переменных. А вот сам текст программы
«на ходу» менять нельзя – если
текст изменен, придется компилировать
заново. Окно просмотра значений переменных
вызывается клавишами Ctrl+F7
(Рис. 2 .4).

Если отладка это процесс удаления ошибок в программе то программирование это

Рис.
2.3
— Точка прерывания.

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

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

Если отладка это процесс удаления ошибок в программе то программирование это

Рис.
2.4
— Окно просмотра значений переменных.

Кстати,
а как продолжить выполнение программы,
остановленной на точке останова? Очень
просто – нажав F9.
Для полного же прерывания выполнения
программы служат клавиши Ctrl+F2.

Если
в программе есть циклы, то отладка
затрудняется – при каждой итерации
придется нажимать Ctrl+F7,
вводить имя переменной, и так не один
десяток раз. Для удобства помимо обычного
окна просмотра в Delphi
предусмотрено и так называемое окно
постоянного просмотра (вызывается
клавишами Ctrl+Alt+W).
В него вводятся (при помощи клавиши
Insert)
переменные и выражения, значения которых
постоянно отображаются. Как только
программа остановилась на точке останова,
все значения уже на экране (Рис. 2 .5).

Если отладка это процесс удаления ошибок в программе то программирование это

Рис.
2.5
— Окно постоянного просмотра.

А
можно ли выполнять программу пошагово,
по одной строке? Да, конечно. Для этого
служат клавиши F4, F7 и F8. Клавиша F4 запускает
программу до курсора, F7–с заходом в
процедуры/функции, F8–без захода в
процедуры/функции. Текущая выполняемая
строка в программе отмечается синей
полосой. Для сброса программы (досрочного
прекращения ее работы) предназначена
комбинация клавиш Ctrl+F2.

Раздел: Статьи /
С/С++ /
Ошибки программирования /

Закон Мэрфи

“Если отладка — это устранение ошибок, стало быть, программирование — это процесс
их создания”. Закон Мэрфи.

“Программирование — это процесс создания ошибок в программах”. “Отладка программ — это процесс создания новых ошибок в программе с целью устранения старых ошибок”.

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

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

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

Если отладка это процесс удаления ошибок в программе то программирование это

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

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

Если отладка это процесс удаления ошибок в программе то программирование это

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

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

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

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

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

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

3 + 5 * 6

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

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

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

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

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

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

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

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

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

Читать также:  Ошибка сети не могу скачать программу

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

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

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

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

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

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

Викторина

input = Hippo’
if input == ‘Hippo’:
print ‘Hello, Hippo’

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

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

Текущая версия страницы пока не проверялась опытными участниками и может значительно отличаться от версии, проверенной 7 апреля 2022 года; проверки требуют 9 правок.

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

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

Если отладка это процесс удаления ошибок в программе то программирование это

Запись в журнале компьютера из Марк II, с мотыльком, приклеенным к странице

Существуют две взаимодополняющие технологии отладки:

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

Место отладки в цикле разработки программыПравить

Типичный цикл разработки, за время жизни программы многократно повторяющийся, выглядит примерно так:

  • Программирование — внесение в программу новой функциональности, исправление существующих ошибок.
  • Тестирование (ручное или автоматизированное; программистом, тестировщиком или пользователем; «дымовое», в режиме чёрного ящика или модульное) — обнаружение факта ошибки.
  • Воспроизведение ошибки — выяснение условий, при которых ошибка случае Это может оказаться непростой задачей при программировании параллельных процессов и при некоторых необычных ошибках, известных как гейзенбаги.
  • Отладка — обнаружение причины ошибки.

ИнструментыПравить

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

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

Также полезными инструментами в руках программиста могут оказаться:

  • Профилировщики. Они позволят определить, сколько времени выполняется тот или иной участок кода. Анализ покрытия позволяет выявить неисполняемые участки кода
  • API логгеры позволяют отследить взаимодействие программы и Windows API при помощи записи сообщений Windows в лог
  • Дизассемблеры позволяют посмотреть ассемблерный код исполняемого файла
  • Снифферы помогут отследить сетевой трафик, генерируемый программой
  • Снифферы аппаратных интерфейсов позволяют увидеть данные, которыми обмениваются система и устройство
  • Логи системы.

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

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

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

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

Инструменты, снижающие потребность в отладке

Другое направление — сделать, чтобы отладка нужна была как можно реже. Для этого применяются:

  • Контрактное программирование — чтобы программист подтверждал другим путём, что ему на выходе нужно именно такое поведение программы. В языках, в которых контрактного программирования нет, используется самопроверка программы в ключевых точках.
  • Модульное тестирование — проверка поведения программы по частям.
  • Статический анализ кода — проверка кода на стандартные ошибки «по недосмотру».
  • Высокая культура программирования, в частности, паттерны проектирования, соглашения об именовании и прозрачное поведение отдельных блоков кода — чтобы объявить себе и другим, каким образом должна вести себя та или иная функция.
  • Широкое использование проверенных внешних библиотек.

Безопасность программного кода и отладкаПравить

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

  • Выявление недокументированного поведения системы
  • Устранение небезопасного кода

Выделяют такие методы:

  • статический анализ кода. На этой фазе программа сканер ищет последовательности в исходном тексте, соответствующие небезопасным вызовам функций и т. д. Фактически идет сканирование исходного текста программы на основе специальной базы правил, которая содержит описание небезопасных образцов кода.
  • фаззинг. Это процесс подачи на вход программы случайных или некорректных данных и анализ реакции программы.
  • Reverse engineering (Обратная инженерия). Этот случай возникает, когда независимые исследователи ищут уязвимости и недокументированные возможности программы.
  • Стив Магьюир, «Создание надёжного кода» (Steve Maguire. Writing Solid Code. Microsoft Press, 1993)
  • Стив Мак-Коннел, «Совершенный код» (Steve McConnel. Code Complete. Microsoft Press, 1993)

СсылкиПравить

  • AMD64 Instruction-Level Debugging With dbx (англ.)
  • AMD64 Instruction-Level Debugging with Sun Studio dbx (англ.)

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

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

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

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

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

Методы тестирования программ

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

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

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

Неавторское
тестирование
(стороннее, его еще называют методом
«черного ящика») – проверка программы
с точки зрения пользователя. Тестовые
примеры подбираются исходя из реальных
ситуаций, возникающих в ходе эксплуатации.

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

Средства отладки программ в Delphi

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

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

Ошибки
времени выполнения (Run-time
error) возникают не при каждом запуске
программы, а лишь при определенном
наборе входных данных (например, делении
на ноль или вводе некорректной даты).
Для их выявления требуется тщательно
подготовить тестовые примеры. Если
причиной являются не программные ошибки,
а действия пользователя, то в программе
должна быть предусмотрена обработка
исключительных ситуаций (см. § 5).

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

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

Соседние файлы в папке ИТ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *