3.7 – Использование встроенного отладчика: запуск и точки останова

Добавлено 20 апреля 2021 в 19:01

Пошаговое выполнение (рассматривается в уроке «3.6 – Использование встроенного отладчика: пошаговое выполнение») полезно для изучения каждой отдельной строки вашего кода изолированно. Но в большой программе может потребоваться много времени, чтобы пройти через весь код, чтобы даже добраться до точки, которую вы хотите изучить более подробно.

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

Выполнение до курсора

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

Для пользователей Visual Studio


В Visual Studio к команде выполнения до курсора можно получить доступ, кликнув правой кнопкой мыши на инструкции в коде и выбрав в контекстном меню Выполнить до текущей позиции (Run to Cursor), или нажав комбинацию клавиш Ctrl + F10.

Для пользователей Code::Blocks


В Code::Blocks к команде «выполнить до курсора» можно получить доступ, кликнув правой кнопкой мыши на инструкции в коде и выбрав либо Run to Cursor (Выполнить до курсора) из контекстного меню, либо меню Debug (Отладка) → Run to Cursor (Выполнить до курсора), либо нажав клавишу F4.

Давайте попробуем эту команду с помощью той же программы, которую мы использовали в предыдущем уроке:

#include <iostream>
 
void printValue(int value)
{
    std::cout << value;
}
 
int main()
{
    printValue(5);
 
    return 0;
}

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

Рисунок 1 Положение маркера выполнения после запуска выполнения до курсора для строки 5
Рисунок 1 – Положение маркера выполнения после запуска выполнения до курсора для строки 5

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

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

Продолжение

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

Для пользователей Visual Studio


В Visual Studio к команде продолжить можно получить доступ во время отладки программы через меню Отладка (Debug) → Продолжить (Continue), или нажав клавишу F5.

Для пользователей Code::Blocks


В Code::Blocks к команде продолжить можно получить доступ во время отладки программы через меню Debug (Отладка) → Start / Continue (Запуск / Продолжить), или нажав клавишу F8.

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

Запуск

У команды продолжить есть брат-близнец по имени запуск. Команда Запуск (Start) выполняет то же действие, что и продолжить, только начиная с самого начала программы. Её можно вызвать только тогда, когда сеанс отладки еще не запущен.

Для пользователей Visual Studio


В Visual Studio к команде запуска можно получить доступ, когда отладка программы еще не выполняется, с помощью меню Отладка (Debug) → Начать отладку (Start Debugging) или путем нажатия клавиши F5.

Для пользователей Code::Blocks


В Code::Blocks к команде запуска можно получить доступ, когда отладка программы еще не выполняется, с помощью меню Debug (Отладка) → Start / Continue (Запуск / Продолжить), или нажав клавишу F8.

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

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

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

Для пользователей Visual Studio


В Visual Studio вы можете установить или удалить точку останова через меню Отладка (Debug) → Вставить точку останова (Insert breakpoint) / Удалить точку останова (Delete breakpoint), или кликнув правой кнопкой мыши на инструкции и выбрав в контекстном меню Вставить точку останова (Insert breakpoint) / Удалить точку останова (Delete breakpoint), либо нажав клавишу F9, либо кликнув слева от номера строки (в светло-серой области).

Для пользователей Code::Blocks


В Code::Blocks вы можете установить или удалить точку останова через меню Debug (Отладка) → Toggle breakpoint (Переключить точку останова), или кликнув правой кнопкой мыши на инструкции и выбрав в контекстном меню Toggle breakpoint (Переключить точку останова), либо нажав клавишу F5, либо кликнув справа от номера строки.

Когда вы установите точку останова, вы увидите значок нового типа. Visual Studio и Code::Blocks используют красный кружок:

Рисунок 2 Индикация точки останова в строке 5
Рисунок 2 – Индикация точки останова в строке 5

Установите точку останова в строке 5, как показано на изображении выше.

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

Рисунок 3 Отладчик остановился в точке останова в строке 5
Рисунок 3 – Отладчик остановился в точке останова в строке 5

Это как если бы вы запустили выполнение до курсора в этой точке.

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

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

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

#include <iostream>
 
void printValue(int value)
{
    std::cout << value;
}
 
int main()
{
    printValue(5);
    printValue(6);
    printValue(7);
 
    return 0;
}

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

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

Задать следующую инструкцию

Есть еще одна команда отладки, которая используется довольно редко, но, по крайней мере, о ней стоит знать, даже если вы не будете использовать ее очень часто. Команда Задать следующую инструкцию (Set next statement) позволяет нам изменить точку выполнения на какую-либо другую инструкцию (иногда неофициально называется прыжком). Её можно использовать для прыжка вперед к точке выполнения и пропуска кода, который в противном случае выполнялся бы, или назад для того, чтобы что-то, что уже было выполнено, запустилось снова.

Для пользователей Visual Studio


В Visual Studio вы можете перейти к точке выполнения, кликнув на инструкции правой кнопкой мыши и выбрав Задать следующую инструкцию (Set next statement) в контекстном меню, или нажав комбинацию клавиш Ctrl + Shift + F10. Этот пункт является контекстным и появляется только при отладке программы.

Для пользователей Code::Blocks


В Code::Blocks вы можете перейти к точке выполнения через меню Debug (Отладка) → Set next statement (Задать следующую инструкцию), или кликнув правой кнопкой мыши на инструкции и выбрав Set next statement (Задать следующую инструкцию) в контекстном меню. Code::Blocks не имеет сочетания горячих клавиш для этой команды.

Давайте посмотрим, как прыгать вперед:

#include <iostream>
 
void printValue(int value)
{
    std::cout << value;
}
 
int main()
{
    printValue(5);
    printValue(6);
    printValue(7);
 
    return 0;
}

Сначала запустите выполнение до курсора в строке 11. На этом этапе вы должны увидеть значение 5 в окне консоли.

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

Результат работы вашей программы должен выглядеть так:

57

Мы видим, что вызов printValue(6) был пропущен.

Эта функция может быть полезна в нескольких контекстах.

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

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

С тем же кодом, приведенным выше, запустите выполнение до курсора в строке 12. Затем задайте следующую инструкцию на строку 11 и выполните команду продолжить. Результат работы программы должен быть следующим:

5667

Предупреждение


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

Предупреждение


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

Заключение

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

Теги

C++ / CppCode::BlocksDebugIDELearnCppVisual StudioДля начинающихОбучениеОтладкаОтладчик / DebuggerПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.