Как поставить точку останова в Visual Studio 2019

Обновлено: 20.11.2024

Самое первое, что вам нужно знать об отладке, — это точка останова. На самом деле он делает именно то, что следует из названия — он отмечает точку в вашем коде, где выполнение прервется (и нет, на самом деле это не сломает ваш код, не волнуйтесь). Размещение точки останова в Visual Studio или одной из версий Express так же просто, как щелчок левой кнопкой мыши в поле слева от вашего кода. Как только вы щелкнете по нему, вы получите в качестве награды блестящий красный кружок — этот кружок отмечает место, где отладчик остановится, когда вы запустите свое приложение. Вам лучше посмотреть на себя, и чтобы увидеть эффект, мы будем использовать следующий фрагмент кода:

Можете ли вы предсказать результат, просто взглянув на код? Возможно, а если нет, то можно просто взять старый калькулятор и посчитать, но суть не в этом. Только представьте, что количество кода намного больше, и давайте его отлаживать! Поместите точку останова, щелкнув в левом поле — теперь ваша среда IDE должна выглядеть примерно так:

Хорошо, вы готовы начать свой первый сеанс отладки. Как только вы установили точку останова, вы можете просто запустить свое приложение, как обычно — из меню, панели инструментов или нажав F5. Теперь происходит то, что приложение выполняется как обычно, но как только достигается строка с точкой останова, выполнение останавливается прямо перед выполнением этой строки. В данном случае это означает, что переменные a, b и c будут иметь значение, а переменная d будет иметь только значение по умолчанию (которое равно 0 для целого числа), так как оно не будет установлено до того, как строка с точкой останова будет был оценен. Теперь самое интересное — попробуйте навести указатель мыши на разные переменные — IDE сообщит вам, что они содержат. Как уже упоминалось, переменная d будет иметь значение по умолчанию, но давайте изменим это, продвинувшись вперед в выполнении. В следующей главе я покажу вам, как перемещаться по коду во время его выполнения.

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

Чтобы выполнить действия, описанные в этой главе, установите решение, как описано в разделе "Подготовка среды курса".

Добавить несколько точек останова

Вернемся к расследованию, начатому в предыдущей главе. Нам нужно приостановить выполнение перед вызовом метода CreateTask в строке 19 файла T_TodoModel.cs для модульного теста VerifyAddTasks.

Точка останова может быть установлена ​​несколькими способами:

Нажмите на поле строки.

Щелкните правой кнопкой мыши точку останова | Вставьте точку останова в инструкцию:

Вы также можете использовать сочетание клавиш F9 в редакторе кода с курсором на инструкции.

Инструкция, о которой идет речь, отображается в редакторе кода красным цветом, а красная точка указывает на это на полях:

Просмотр точки останова в редакторе Visual Studio

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

Отладка модульного теста

Как и ожидалось, выполнение приостановлено:

Просмотр точки останова в редакторе Visual Studio

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

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

Установка точки останова на конкретной инструкции

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

Управление точками останова

При расследовании может потребоваться определить несколько точек останова. Visual Studio предлагает графический интерфейс для запроса отладчика на временное игнорирование или удаление их.Вы можете получить доступ к этому списку определенных точек останова из Debug | Окна | Меню точек останова:

Меню для отображения точек останова

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

Панель "Точки останова"

Если ваша текущая теория неверна, это позволит выполнить выполнение более плавно, не теряя контрольных точек.

Есть несколько способов удалить точку останова, которая вам больше не нужна::

Выберите точку останова на панели "Точки останова" и нажмите красный крестик на панели инструментов.

Используйте сочетание клавиш F9 в строке непосредственно в редакторе кода.

Нажмите точку на поле или щелкните правой кнопкой мыши Точка останова | Удалить точку останова.

Подведем итоги!

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

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

Visual Studio (VS) — не единственный отладчик в нашем распоряжении (у нас также есть WinDbg, Rider и dnSpy). Но Visual Studio является наиболее широко используемым, и именно ему посвящена эта статья. VS может показаться простым для начала, но у него очень много функций, которые имеют решающее значение для эффективной отладки. Освоение отладки в Visual Studio сократит время отладки и сделает вас более эффективным разработчиком.

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

1. Подключение отладчика

Отладка в Visual Studio выполняется автоматически при запуске из Visual Studio с помощью клавиши F5 или выбора Отладка | Начать отладку.

При этом Visual Studio присоединялась к программе в качестве отладчика. Кроме того, вы можете подключиться к запущенному процессу с помощью Debug | Присоединить к процессу… (Ctrl+Alt+P).

2. Режим остановки отладчика

Отлаживаемый процесс должен находиться в "Режиме останова" для отладки. Это означает, что программа в данный момент приостановлена ​​на определенной строке кода. Точнее, все запущенные потоки приостанавливаются на определенной строке кода.

Вы можете перейти в режим приостановки, выбрав Отладка | Пункт меню «Разбить все» (Ctrl+Alt+Break) или поставив точки останова.

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

Точки останова можно размещать, щелкая по краю, нажимая F9 или Debug | Переключить точку останова. После установки, когда ваша программа достигнет этой строки кода, отладчик Visual Studio прекратит выполнение и перейдет в «Режим останова»:

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

3. В режиме перерыва — навигация по коду

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

Переход (F10) выполнит текущую строку и прервет следующую строку кода.

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

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

  • Наведите курсор и нажмите на зеленую стрелку, которая появляется в начале каждой строки.

  • Встаньте на нужную строку кода и нажмите Ctrl + F10.
  • Щелкните правой кнопкой мыши по нужной строке кода и выберите "Задать следующий оператор".

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

  • Перетащите желтую стрелку на любую строку кода.
  • Встаньте на нужную строку кода и нажмите Ctrl+Shift+F10.

4. Исследуйте переменные

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

Всплывающее окно называется всплывающей подсказкой. Вы можете перейти к тому же всплывающему окну, щелкнув переменную правой кнопкой мыши и выбрав QuickWatch (Shift+F9 или Ctrl+D, Q) в контекстном меню.

Подсказка по данным и QuickWatch очень похожи, за исключением того, что вы можете редактировать выражение в QuickWatch.

Выражение – это последовательность переменных и операторов, результатом которой является одно значение. Например, DiscountPercentage является выражением, initialPrice / 100 * DiscountPercentage также является выражением, такие литералы, как «Hello world» и 5, также являются выражениями.

Для сложных объектов вы можете расширить поля и свойства.

5. Важные особенности DataTip и QuickWatch

Подсказка по данным и QuickWatch имеют несколько полезных функций:

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

  • Копировать — копирует в буфер обмена как выражение, так и значение ( alex = )
  • Копировать выражение — копирует выражение ( alex )
  • Копировать значение — копирование выражения ( )
  • Редактировать значение — полезная функция, позволяющая изменить значение во время отладки. Наиболее полезно для примитивов (строки, целые числа и т. д.).
  • Добавить отслеживание — добавляет выражение в окно просмотра (подробнее об этом позже).
  • Добавить Parallel Watch — добавляет выражение в окно Parallel Watch (подробнее об этом позже)
  • Создать идентификатор объекта. Создает выражение, не зависящее от области действия, которое начинается с символа $ ($1, $2 и т. д.). Вы можете оценить это выражение в любое время, независимо от текущей области, в QuickWatch, Watch Window или Immediate Window. Очень полезная функция, которую можно использовать для обнаружения утечек памяти.

6. Расширенные функции точки останова

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

  • Условия позволяют выполнить останов на этой точке останова только при выполнении условия. Например, в цикле я могу прерваться только на четных числах:

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

Это наиболее полезно при отладке многопоточных сценариев. Подробнее о многопоточной отладке позже.

  • Редактировать метки… позволяет классифицировать точки останова по меткам. Это упрощает их организацию в окне инструментов точек останова в дальнейшем:

Обзор

Мы рассмотрели самые основы отладки в Visual Studio, поэтому я надеюсь, что вы освоите этот материал, потому что следующее руководство будет более сложным.

В следующем руководстве мы углубимся в окна инструментов Visual Studio. К ним относятся: непосредственное окно, окна наблюдения, локальные переменные, автоматические параметры, стек вызовов, потоки, точки останова, исключения и окно вывода.

Есть и другие окна инструментов, но они не являются частью основных функций отладки, и мы рассмотрим их в соответствующем контексте. К ним относятся окно «Модули», «Процессы», «Задачи», «Параллельное наблюдение», «Параллельные стеки», «Разборка» и «Память».

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

Подписаться

Присоединяйтесь к списку рассылки и получайте обновления о новых статьях


Алекс Аллен

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

Здесь вы узнаете о некоторых более продвинутых функциях отладчика Visual Studio, таких как выход из функции, использование преимуществ автоматического окна, использование запуска до курсора для установки временных точек останова, изменение значения переменной для проверки потенциальные исправления и использование оператора Set Next, чтобы повернуть время вспять и повторно выполнить код.

Пример (багги) кода

1. Выйдите из текущей функции

Итак, вы написали вызов функции, например: И функция calculate_average не возвращает правильное значение. Если бы вы воспользовались отладчиком и захотели перейти к функции calculate_average, вы, конечно, могли бы поставить точку останова внутри calculate_average, но что, если бы она вызывалась из нескольких мест? Visual Studio имеет очень удобную функцию отладчика, которая позволит вам очень быстро перейти к calculate_average.

Установите точку останова в этой строке:

После того, как отладчик доберется до него, войдите в функцию. getSum и getCount будут вызываться раньше, чем calculate_average. Обычно, чтобы выйти из функций getSum и getCount, вы продолжаете нажимать Next, но в Visual Studio вы можете быстро нажать Shift-F11, чтобы выйти из текущей функции и вернуться к следующему вызову.

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

Когда использовать этот трюк

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

2. Используйте автоматическое окно для просмотра результатов функций

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

Иногда программисты пишут такой код, просто чтобы обойти проблему: (Очевидно, что в этом случае программа выводит значение, так что не все потеряно. В общем случае это редко бывает так.)

К счастью, окно autos удобно отображать результат оценки функции:

Когда использовать этот прием

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

Знаете ли вы.

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

3. Бежать к курсору

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

По сути, run-to-cursor — это просто ярлык для установки точки останова, которая сразу же сбрасывается после достижения; тем не менее, это очень удобная функция. Это наиболее полезно, когда у вас есть фрагмент кода, который часто вызывается из разных мест, и вас интересует только один путь кода. Затем вы можете поставить точку останова в начале этого пути и использовать run-to-cursor, чтобы добраться до нужной вам точки.

Возвращаясь к нашему примеру программы, мы можем использовать метод запуска к курсору, а не трюк с выходом, чтобы попасть в вычисление_среднего.(Конечно, мы могли бы просто поставить точку останова в calculate_average; чтобы сделать этот пример осмысленным, представьте себе 15-20 вызовов calculate_average, которые все работают правильно и происходят до неработающего вызова.)

Когда использовать этот прием

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

4. Изменить любую переменную

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

Очевидно, что один из способов сделать это — передать новое значение. Но Visual Studio удобно упрощает изменение любого значения в памяти. На самом деле, давайте сделаем это со значением sum и убедимся, что оно возвращает правильное значение.

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

Продолжение выполнения программы показывает, что на самом деле мы по-прежнему получаем неверный ответ — на этот раз она возвращает значение 1. Это говорит о том, что происходит усечение из-за целочисленного деления.

Перед компиляцией мы можем добавить приведение, чтобы решить эту проблему:

Когда использовать этот прием

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

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

5. Установить следующий оператор

Set Next Statement – это действительно мощный инструмент. Если вы занимаетесь отладкой и случайно (или не совсем случайно) перешагнули через точку, где происходит что-то интересное, иногда можно «отмотать» выполнение. На самом деле это означает, что, сохраняя текущее состояние мира, вы можете указать Visual Studio вернуться и начать выполнение с предыдущей инструкции.

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

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

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

Если вы случайно забежали слишком далеко, может быть очень удобно иметь возможность просто сказать: "Хорошо, давайте начнем снова":

и затем вы можете вернуться к выполнению цикла, возможно, установив значение total равным 0, поскольку вы заметили, что оно не было инициализировано, а затем проверить, дает ли программа правильную сумму (в этом случае, вы можете быть уверены, что проблема заключалась в отсутствии инициализации).

Когда использовать этот прием

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

Читайте также: