Урок 26. Отладка программ. Stepping и breakpoints

   ⁄ 

 Обновлено 24 Фев 2017

  ⁄   

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

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

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

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

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

Иногда они могут производить неверные результаты:

Либо

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

В примерах выше, ошибки довольно легко обнаружить. Но в большинстве других программах (свыше 40 строк), семантические ошибки уловить с помощью простого просмотра кода будет не так-то просто.

И здесь на помощь приходит отладчик.

Отладчик

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

Более ранние дебаггеры, такие как GDB, имели интерфейс командной строки, где программисту приходилось вводить специальные команды для старта работы. Более современные дебаггеры (например, Turbo Debugger от Borland), уже имеют свой собственный «графический» интерфейс, что значительно упрощает работу с ними. Сейчас почти все современные IDE идут в комплекте со встроенными отладчиками. То есть, дебаггер уже встроен в редактор и вы можете использовать одну среду и для отладки, и для написания кода (вместо постоянного переключения между программами).

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

Перед тем как продолжить: Убедитесь, что вы находитесь в режиме конфигурации Debug.

Stepping

Stepping (степпинг) — это возможность отладчика выполнять код строка за строкой (пошагово). Есть три разные команды stepping: step into, step over и step out. Мы рассмотрим каждую из них по очереди.

Step into

Команда step into выполняет следующую строку кода. Если эта строка является вызовом функции, step into открывает функцию и выполнение переносится в начало этой функции.

Давайте рассмотрим очень простую программу:

Как вы уже знаете, при запуске программы, выполнение начинается с вызова главной функции main(). Так как мы хотим сделать отладку внутри main(), давайте начнем, используя команду «Step into».

В Visual Studio, перейдите в меню Debug и выберите «Step Into», либо нажмите клавишу F11. Если вы используете другую IDE, найдите в меню команду «Step Into» и выберите её.

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

ris1

Стрелка-маркер указывает на следующую линию, которая будет выполняться. В этом случае отладчик говорит нам, что следующей строкой, которая будет выполняться, будет открывающая фигурная скобка функции main(). Выберите «Step into» еще раз, чтобы выполнить открывающую фигурную скобку, затем стрелка переместится на следующую строку.

ris2

Это значит, что следующей строкой, которая будет выполняться, будет вызов функции printValue(). Выберите «Step into» снова. Поскольку printValue() — это вызов функции, мы как бы сделаем step into (шаг в) функцию и стрелка переместиться в верхнюю часть printValue().

ris3

Выберите еще раз «Step into» для выполнения открывающей фигурной скобки printValue().

Теперь стрелка должна указывать на std::cout << nValue;.

Теперь выберите «Step over» (F10). Поскольку выполнение перешло к cout, вы должны увидеть значение 5 в консольном окне.

Выберите «Step into» еще раз для выполнения закрывающей фигурной скобки printValue(). printValue() завершит выполнение и стрелка переместиться в main().

Обратите внимание, что в main() стрелка снова указывает на printValue()!

ris4

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

Выберите «Step into» два раза. Готово, все строки кода выполнены. Некоторые дебаггеры автоматически прекращают сеанс отладки в этой точке. Но Visual Studio так не делает, так что если вы используете Visual Studio, выберите «Stop Debugging» в меню Debug. Это позволит полностью прекратить сеанс отладки.

Обратите внимание, что «Stop Debugging» можно использовать в любой момент в процессе отладки для её завершения.

Step over

Как и «Step into», шаг Step over выполняет следующую строку кода. Только если строка будет вызовом функции, «Step over» выполнит за одно нажатие весь код функции и возвратит контроль нам после того, как функция будет выполнена.

Примечание для пользователей Code::Blocks: в Code::Blocks команда «Step over» называется «Next Line».

Давайте рассмотрим пример, используя программу выше:

Нажимайте “Step into” до тех пор, пока следующей строкой, которая будет выполняться, будет вызов функции printValue().

ris5

Вместо «Step into» выберите «Step over». Отладчик выполнит функцию (которая выводит значение 5 в консоль), а затем возвратит управление нам на следующей строке (return 0;) за одно нажатие.

Шаг «Step over» обеспечивает удобный способ пропуска функций, когда мы уверены, что они работают, как должны и их не нужно отлаживать.

Step out

В отличие от двух предыдущих команд, “Step out” не просто выполняет следующую строку кода. Он выполняет весь оставшийся код функции, в которой вы сейчас находитесь, и возвращает контроль только после того, как функция завершит выполнение. Проще говоря, «Step out» (в переводе «выйти») выходит из функции.

Обратите внимание: команда “Step out” появится в меню Debug только после старта процесса отладки, который можно начать, используя одну из двух предыдущих команд.

Давайте рассмотрим пример, используя программу выше:

Нажимайте “Step into” до тех пор, пока не будете внутри printValue().

ris6

Затем выберите “Step out”. Вы заметите, что значение 5 отобразится в консольном окне, и отладчик возвратит контроль после того, как функция выполнится.

Run to cursor

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

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

Run to cursor – это еще одна полезная команда. Здесь мы выполняем программу, как обычно, только до строки, которая обозначена курсором. Затем контроль переходит нам и мы можем проводить отладку с той точки уже более подробно. Давайте попробуем, используя программу выше:

Поместите курсор на строку std::cout << nValue; внутри printValue(), затем щелкните правой кнопкой мыши и выберите “Run to cursor”.

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

Continue

Если вы находитесь в середине процесса отладки вашей программы, вы можете сообщить отладчику продолжать выполнение до тех пор, пока он не дойдет до конца программы (или следующей контрольной точки). В Visual Studio, эта команда называется «Continue». В других дебаггерах она может иметь название «Run» или «Go».

Возвращаясь к примеру выше, мы находимся как раз внутри функции printValue(). Выберите команду «Continue» в меню Debug (или нажмите F5) — программа завершит выполнение, затем закроется.

Breakpoints

Breakpoints (точки останова) – это специальные маркеры, в местах размещения которых отладчик останавливает выполнение.

Для установки breakpoint в Visual Studio, перейдите в меню Debug и выберите «Toggle Breakpoint» (вы также можете щелкнуть правой кнопкой мыши, выбрать Breakpoint > Insert Breakpoint). Вы увидите новый тип значка:

ris7

В программе выше, создайте breakpoint на строке std::cout << nValue;.

Теперь, выберите «Step into» для старта сеанса отладки, а затем «Continue» для того, чтобы отладчик запустил ваш код. Вы заметите, что вместо того, чтобы продолжать выполнение до конца программы, отладчик остановится в указанной вами точке!

ris8

Breakpoints чрезвычайно полезны, если вы хотите изучить только определенную часть кода. Просто задайте точку останова в определенном участке кода, нажмите команду Continue, и отладчик автоматически остановится возле определенной строки. Затем вы можете использовать команды stepping для более детального просмотра программы (строка за строкой).

Последнее примечание: До сих пор мы использовали команду “step into” для начала отладки. Тем не менее, мы можем сообщить дебаггеру сразу выполнить весь код до конца программы. В Visual Studio это делается путем выбора “Start debugging” в меню Debug. Другие отладчики имеют аналогичные команды.

Результат

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

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (14 оценок, среднее: 4,71 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

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

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