Практикум по Delphi для решения прикладных задач
f65d50f6

Методы отладки и борьбы с ошибками


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

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

Однако, несмотря на предупреждение, программа может запуститься. Если вводятся дкакие-либо данные, то появляется сообщение об исключительной ситуации – exception. При этом программа приостанавливается, переходя из режима исполнения в режим отладки. Чтобы перейти к обычному редактированию кода, лучше остановить программу. Это можно сделать с помощью команды Program Reset. Затем можно поправить ошибку и вновь запустить программу.

В большие программы всегда закрадываются ошибки. Их надо быстро и квалифицированно найти и исправить. Механизм исключительных ситуаций (exception) – одно из больших достоинств Delphi. С их помощью вы можете контролировать возникновение ошибок и создавать в результате устойчивые к ошибкам программы.

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

Опасность таких скрытых ошибок состоит:

1)      в том, что они таятся в той части кода, которую программист написал и уверен, что она правильная (программа запустилась), а значит, и не очень внимательно будет искать ошибку;

2)      в том, что проявляется эта ошибка совсем в другом месте кода – не в том, в котором допущена. А это приводит к долгим поискам ее по всей программе.

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

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

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

Чтобы выполнить текущую строку, на которой стоит курсор отладки, нажмите F7 или F8. Строка выполнилась, и курсор сместился. Если необходимо перейти к следующей строке, то можно нажать F8, если нужно зайти в какую-либо функцию, то нажимают клавишу F7 и продолжают трассировку.

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



Это, однако, работает не со всеми переменными, а только с доступными в данный момент. Если нужно постоянно контролировать значение переменной, то еще проще добавить ее в список Watch. Для более основательного слежения за значениями можете воспользоваться Списком Наблюдения (Watch List, Ctrl+F5).

Таким образом, при программировании среда Delphi может находиться в различных режимах:

  • Режим редактирования – режим, в котором редактируется код проекта, модифицируется форма, добавляя на нее компоненты и настраивая их свойства. Это основной режим.
  • Режим исполнения программы – режим, в который среда переходит, как только  нажата клавиша F9 и был построен exe-файл. Фактически, в этом режиме происходит как раз исполнение получившегося exe-файла проекта. Программа исполняется так, как если бы ее вызвали не из Delphi, а просто из Windows.
  • Режим отладки – в этот режим можно перейти из режима исполнения программы. При этом программа будет приостановлена (но не остановлена совсем).

Чтобы продолжить трассировку (последовательный переход от команды к команде), можете воспользоваться клавишами:

  • F9 (Run) – продолжить программу, не трассируя ее.
  • F8 (Step over) – выполняется текущая строка кода, и переходят к следующей строке.
  • F7 (Trace Into) – то же, что и F8, с тем отличием, что если в текущей строчке содержится вызов какой-либо функции или процедуры, то попадают внутрь этой процедуры и трассируют ее до конца, затем из нее возвращаетс и переходят к следующей строке (на которую перешли бы сразу, если бы нажали F8).
  • F4 (Run to Cursor) – переход в режим исполнения программы до тех пор, пока не должна будет выполнена строка, на которой стоит текстовый курсор (аналогично тому, как если бы была установлена точка останова)
  • Shift+F8 (Run Until Return) – процедура выполняется до конца.
  • Ctrl+F2 (Program Reset) – остановка трассировки и переход в режим редактирования кода. (Иногда целесообразнее, если это не грозит ошибками, продолжить исполнение программы (F9) и выйти из нее нормальным образом, закрыв главную форму).

При работе в Delphi сообщение об ошибке фактически появляется дважды: сначала выводится окно об исключительной ситуации и программа приостанавливается, а потом, если нажать F9 (F8, F7 и т.п.), – возникает стандартное сообщение об ошибке Windows.

Итак:

  1. Произошла ошибка.
  2. Программа приостанавливается.
  3. Выводится сообщение об exception. Это сообщение для программиста. Среда Delphi сообщает, что программа не в состоянии выполнить какую-то свою команду. Программист не предусмотрел возможность исключительной ситуации.  Среда Delphi приостанавливает программу, чтобы программист разобрался, где и в чем ошибка. Отключить приостановку (2)–(3) можно, сняв флажок Menu => Tools => Debugger Options => Language Exceptions => Stop on Delphi Exceptions.
  4.  Нажатие клавиши F9 (F8, F7 или др.).
  5. Выводится сообщение об ошибке. Это сообщение для пользователя программы (ситуация запуска приложения не из Delphi, а через exe-файл из Windows, т.е. не существовует пунктов 2, 3, 4).
  6. Программа продолжается (при этом она не сумела выполнить ту часть, в которой произошла ошибка, и значит, если эта часть важная, продолжение может сопровождаться дальнейшими ошибками).

Механизм обработки исключительных ситуаций заключается в том, что если произошла ошибка (1) и не надо выводить (5), предпринимаются действия, чтобы (6) исполнялось корректно. Для этого «опасная» команда (или целый блок) помещается внутрь конструкции try..except..end или try..finally..end.

Блок try..finally..end используется аналогично try..except.., но с тем отличием, что блок команд между finally и end выполняется в любом случае, вне зависимости от того, было исключение между try и finally или нет.



Содержание раздела