Pull to refresh

Советы по отладке в Visual Studio 2010

Reading time8 min
Views73K
Original author: Scott Guthrie
Это двадцать шестая публикация в серии публикаций о VS 2010 и .NET 4.

Сегодняшняя публикация рассматривает некоторые полезные советы по отладке которые вы можете применять в Visual Studio. Мой друг Скот Кэйт (Scott Cate) (который опубликовал в блоге дюжину великолепных советов и трюков по VS) недавно обратил мое внимание на несколько хороших советов о которых не знает много разработчиков использующих Visual Studio (даже при том, что многие из них работают с ней уже давно с более ранних версий).

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

Run to Cursor (Ctrl + F10) (Выполнить до курсора)

Часто я наблюдаю людей отлаживающих приложения следующим образом: они устанавливают точку останова на много раньше того места которое их интересует, а затем постоянно пользуются F10/F11 чтобы пройти по коду пока не будет достигнуто то место, которое на самом деле они хотят исследовать. В некоторых случаях они внимательно осматривают каждое выражение, через которое они проходят (в таких случаях использование F10/F11 имеет смысл). Однако, чаще, люди просто пытаются быстро перейти к строке кода которая на самом деле их интересует — в таких случаях использование F10/F11 это не лучший способ для достижения такой цели.
Вместо этого, вы можете воспользоватся функцией “run to cursor” («выполнить до курсора») которая поддерживается отладчиком. Просто установите курсор на строке кода до которой вы хотите выполнить приложение, а затем нажмите вместе Ctrl + F10. Это приведет к выполнению приложения до этой строки и переходу в режим отладки сохраняя время которое могло быть потрачено на множественные нажатия F10/F11 для того, чтобы попасть сюда. Это работает даже в тех случаях, когда код в который вы хотите попасть находится в отдельном методе или класс по отношению к тому месту которое вы в данный момент отлаживаете.

Conditional Breakpoints (Условные точки останова)

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

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

Как включить Conditional Breakpoint (Условную точку останова)

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

image

Затем щелкните правой кнопкой мыши на красном кружке точки останова слева от окна редактора и выберите контекстное меню «Condition...» («Условие...»):

image

Это приведет к появлению диалогового окна, которое позволяет указать, что точка останова должна срабатывать только, если определенное условие истинно. Например, мы можем указать, что на нужно переходить в отладку, если размер локального списка paginatedDinners менее 10-и, вписав следующее выражение ниже:

image

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

Функция Hit Count (Число попаданий)

Иногда вам нужно, чтобы происходила остановка отладчика только при условии, что условие истинно N-раз.
Например, останавливаться только, если уже 5 раз поиск возвратил меньше чем 10 обедов.

Вы можете включить такое поведение правым щелчком на точке останова и выбором пункта меню «Hit count...» («Количество попаданий...»).

image

Это приведет к появлению диалогового окна, которое позволяет указать, что точка останова должна быть достигнута только N-раз, когда достигнуто условие или каждые N-раз, когда оно достигнуто, или каждый раз после N вхождений:

image

Фильтрация по Machine/Thread/Process (Имя машины/Поток/Процесс)
Вы можете также щелкнуть правой кнопкой на точке останова и выбрать пункт «Filter...» («Фильтр...») из контекстного меню, чтобы указать, что точка останова должна быть достигнута, если процесс отладки происходит на определенной машине или в определенном процессе или в определенной потоке.

Точки трассировки (TracePoints) – пользовательские события при попадании в точку останова

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

Я использую простое консольное приложение (Console application), чтобы продемонстрировать как мы могли бы воспользоваться Точками трассировки. Ниже приведена рекурсивная реализация ряда Фибоначчи:

image

В приложении приведенном выше мы используем Console.WriteLine() чтобы выводить окончательные значение ряда для конкретного значения диапазона. Что если мы захотели отследить рекурсивную последовательность ряда Фибоначчи в действии одновременно с отладкой – без фактической его остановки или приостановки? Точки трассировки могут помочь нам легко это сделать.

Установка точки трассировки (TracePoint)

Вы можете включить точки трассировки воспользовавшись клавишей F9 для установки точки останова в строке кода и затем щелкнув правой кнопкой на точке останова и выбрав пункт «When Hit...» («Когда Попадает...») из контекстного меню:

image

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

image

Выше мы указали, что хотим выводить трассировочное сообщение каждый раз, когда условие точки останова достигнуто. Заметьте, что мы указали, что мы хотим выводить значение локальной переменной «x» как части сообщения. На локальные переменные можно ссылаться используя синтаксис {variableName}. Также есть встроенные команды (такие как $CALLER, $CALLSTACK, $FUNCTION и т. д.) которые могу использоваться для вывода общих значений в ваши трассировочные сообщения.

Выше мы также поставили флажок напротив «continue execution» («продолжать выполнение») внизу, который указывает на то, что нам не нужно, чтобы приложение останавливалось в отладчике. Наоборот оно будет продолжать выполняться лишь с той разницей, что наше пользовательское сообщение трассировки будет выводится каждый раз, когда будут достигнуты условия точки останова.

А теперь, когда мы выполняем приложение, мы увидим, что наше пользовательское сообщение трассировки автоматически отображается в окне Visual Studio «output» («вывод») позволяя нам следить за рекурсивным поведением приложения:

image

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

Точки трассировки (TracePoints) – выполнение пользовательского макроса

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

Эта возможность не встроена в Visual Studio, но может быть включена при помощи пользовательского макроса и последующей настройки Точки трассировки для вызова макроса, когда эта точка достигнута. Чтобы это выполнить откройте интегрированную среду для макросов внутри Visual Studio (Tools->Macros->Macros IDE menu command). Далее под узлом MyMacros в обозревателе проекта выберите модуль или создайте новый (например: с именем “UsefulThings”). После этого вставьте следующий код макроса на VB в модуль и сохраните его:

VB:
Sub DumpLocals()

    Dim outputWindow As EnvDTE.OutputWindow

    outputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Object

    Dim currentStackFrame As EnvDTE.StackFrame

    currentStackFrame = DTE.Debugger.CurrentStackFrame

    outputWindow.ActivePane.OutputString("*Dumping Local Variables*" + vbCrLf)

    For Each exp As EnvDTE.Expression In currentStackFrame.Locals

      outputWindow.ActivePane.OutputString(exp.Name + " = " + exp.Value.ToString() + vbCrLf)

    Next

  End Sub


* This source code was highlighted with Source Code Highlighter.



C#
void DumpLocals() {
    EnvDTE.OutputWindow outputWindow;
    outputWindow = DTE.Windows.Item[EnvDTE.Constants.vsWindowKindOutput].Object;
    EnvDTE.StackFrame currentStackFrame;
    currentStackFrame = DTE.Debugger.CurrentStackFrame;
    outputWindow.ActivePane.OutputString(("*Dumping Local Variables*" + "\r\n"));
    foreach (EnvDTE.Expression exp in currentStackFrame.Locals) {
      outputWindow.ActivePane.OutputString((exp.Name + (" = "
              + (exp.Value.ToString() + "\r\n"))));
    }
  }


* This source code was highlighted with Source Code Highlighter.



Код макроса приведенный выше циклически проходит по текущему стеку и выводит все переменные в окно вывода.

Использование нашего пользовательского макроса DumpLocals

Затем мы можем использовать наш пользовательский макрос «DumpLocals» простое дополнительное приложение, которое приведено ниже:

image

Мы воспользуемся клавишей F9 для установки точки останова на возвращающее выражение в нашем методе
«Add» приведенном выше. Затем щелкнем правой кнопкой на точке останова и выберем из контекстного меню команду «When hit» («Когда останавливаться»):

image

Это приведет к появлению следующего диалогового окна. В отличие от предыдущего кода, где мы использовали флажок «Print a message» («Выводить сообщение») и в ручную определяли переменные которые мы хотим вывести, в этот раз вместо этого мы выберем флажок «Run a macro» («Выполнить макрос») и укажем макрос UsefulThings.DumpLocals который мы создали выше:

image

Мы оставим флажок «continue execution» («продолжить выполнение»), так чтобы программа продолжала выполняться даже после достижения Точки трассировки.

Запуск приложения

А теперь, когда мы нажмем клавишу F5 и запустим приложение мы увидим следующий вывод в окне «output» («вывод») Visual Studio, когда будет запущен наш метод Add. Заметьте как макрос автоматически выводит в списке имя и значение каждой переменной, когда достигается Точка трассировки:

image

Итог

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

В прошлый раз я написал в блоге о других улучшениях в отладчике VS 2010 (включающих вывод подсказки по типу данных (DataTip), Импорт/Экспорт точек останова, Сохранение последних значений переменных и многое другое). Я буду дальше писать в блоге о новых возможностях VS 2010: Intellitrace, а также поддержке Отладки файла дампа. Публикации буду описывать кучу дополнительных крутейших новых возможностей которые могут сделать отладку приложений еще легче.

Также не забудьте посмотреть превосходную серию Скота Кэйта Visual Studio 2010 Tips and Tricks, чтобы узнать как лучше использовать Visual Studio. У него есть бесподобный набор бесплатных видео и публикаций в блоге.

Надеюсь это поможет,

Scott

P.S. В дополнение к публикациям в блоге, я также теперь использую twitter для быстрых обновлений и обмена ссылками. Следуйте за мной: twitter.com/scottgu
Tags:
Hubs:
+42
Comments31

Articles