Урок №26. Отладка программ: степпинг и точки останова

  Юрий  | 

    | 

  Обновл. 16 Мар 2019  | 

 15808

 ǀ   7 

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

Типы ошибок

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

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

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

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

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

Либо делать вообще не то, что нужно:

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

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

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

Отладчик


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

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

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

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

Степпинг

Степпинг (англ. «stepping») — это возможность отладчика выполнять код пошагово (строка за строкой). Есть три команды степпинга:

   Шаг с заходом.

   Шаг с обходом.

   Шаг с выходом.

Мы рассмотрим каждую из этих команд по очереди.

Команда «Шаг с заходом»


Команда «Шаг с заходом» (англ. «Step into») выполняет следующую строку кода. Если этой строкой является вызов функции, то «Шаг с заходом» открывает функцию и выполнение переносится в начало этой функции.

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

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

В Visual Studio, перейдите в меню «Отладка» > «Шаг с заходом» (либо нажмите F11):

Если вы используете другую IDE, то найдите в меню команду «Step Into/Шаг с заходом» и выберите её.

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

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

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

Выберите ещё раз «Шаг с заходом» для выполнения открывающей фигурной скобки printValue(). Стрелка будет указывать на std::cout << nValue;.

Теперь выберите «Шаг с обходом» (F10). Вы увидите число 5 в консольном окне.

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

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

Выберите «Шаг с заходом» два раза. Готово, все строчки кода выполнены. Некоторые дебаггеры автоматически прекращают сеанс отладки в этой точке. Но Visual Studio так не делает, так что если вы используете Visual Studio, то выберите «Отладка» > «Остановить отладку» (или Shift+F5):

Таким образом мы полностью остановили сеанс отладки нашей программы.

Команда «Шаг с обходом»

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

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

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

Нажмите «Шаг с заходом», чтобы дойти до вызова функции printValue():

Теперь вместо команды «Шаг с заходом» выберите «Шаг с обходом» (или F10):

Отладчик выполнит функцию (которая выведет значение 5 в консоль), а затем возвратит нам управление на строке return 0;. И это всё за одно нажатие.

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

Команда «Шаг с выходом»


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

Обратите внимание, команда “Шаг с выходом” появится в меню «Отладка» только после начала сеанса отладки (что делается путём использования одной из двух команд выше).

Рассмотрим всё тот же пример:

Нажимайте “Шаг с заходом” до тех пор, пока не перейдёте к открывающей фигурной скобки функции printValue():

Затем выберите «Отладка» > «Шаг с выходом» (либо Shift+F11):

Вы заметите, что значение 5 отобразилось в консольном окне, а отладчик перешёл к вызову функции printValue() в main():


Команда «Выполнить до текущей позиции»

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

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

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

Поместите курсор на строку std::cout << nValue; внутри printValue(), затем щёлкните правой кнопкой мыши и выберите “Выполнить до текущей позиции” (либо Ctrl+F10):

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

Команда «Продолжить»

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

Возвращаясь к примеру выше, мы находимся как раз внутри функции printValue(). Выберите «Отладка» > «Продолжить» (или F5):

Программа завершит своё выполнение и выйдет из сеанса отладки.

Точки останова

Точки останова (англ. «breakpoint) — это специальные маркеры, на которых отладчик останавливает процесс выполнения программы.

Чтобы задать точку останова в Visual Studio, щёлкните правой кнопкой мыши на выбранной строке > «Точка останова» > «Вставить точку останова»:

Появится кружочек возле строки:

В программе выше, создайте точку останова на строке std::cout << nValue;. Затем выберите «Шаг с заходом» для старта сеанса отладки, а затем «Продолжить». Вы увидите, что вместо завершения выполнения программы и остановки сеанса отладки, отладчик остановится в указанной вами точке:

Точки останова чрезвычайно полезны, если вы хотите изучить только определённую часть кода. Просто задайте точку останова в выбранном участке кода, выберите команду «Продолжить» и отладчик автоматически остановится возле указанной строки. Затем вы сможете использовать команды степпинга для более детального просмотра/изучения кода.

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

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (153 оценок, среднее: 4,90 из 5)
Загрузка...

Комментариев: 7

  1. Аватар Анастасия:

    Хотелось бы узнать, как выполнить эти действия в других средах. У меня DEV C++ и там ничего подобного не наблюдаю.
    P.S. VS у меня тоже есть, но не могу найти иконку к ней, приходится заходить через установщик, это очень долго. Поэтому использую DEV C++.
    Буду очень признательна, если кто-то подскажет, как найти иконку VS, чтобы вынести её на рабочий стол.

  2. Аватар Виталий:

    Возможно ли, и как осуществлять отладку dll-проектов?

  3. Аватар Николай:

    Не плохо было бы добавит как подключать отладчик, у меня почему то не прописан был путь к нему Code:Blocks . Пришлось гуглить. В Setting-> debugger ->Default->Executable path… указать путь нужного нам отладчика лежит в папке компилятора CodeBlocks\MinGB\bin\gdb32.exe

  4. Аватар Георгий:

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

    1. Аватар shaslataushang:

      Мне пригодилось. Там дальше будет урок по вложенным циклам. И у меня одно задание никак не хотело выполняться правильно, и я не мог понять в чём причина. Начал отладку, наг за шагом следил что и как происходит. Я выявил все причины, программа начала работать именно так, как я и задумывал. Уже третий раз прохожу курс, ибо жизненные обстоятельства то и дело принуждают его забросить… Но я его закончу!

  5. Аватар Александр:

    Ни одного комментария. А тема в программировании самая важная.
    Без отладчика — как без рук.
    joxi.ru/zAN47oWUBwgkPm
    Вот пример нашего отладчика. Вроде горячие клавиши совпадают
    =))

    1. Юрий Юрий:

      Это 1С? Жестко 🙂

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

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