Что нельзя делать в окне watch во время отладки программы
При отладке программ нужно иметь доступ к значениям свойств и переменных, оценивать какие-то выражения. Для этой цели предназначены окна отладки.
Рис.1. Внешний вид окна отладки
Коротко остановимся на назначении каждого из перечисленных окон.
Помимо вывода данных окно Immediate (Проверка) может использоваться для изменения значений переменных. Например, конструкция:
Окно Locals (окальных значений) показывает значения всех переменных текущей процедуры. Содержимое этого окна меняется по мере того, как управление передается от процедуры к процедуре.
Рис.2. Добавление контрольного значения
Итак, нами изучены средства Microsoft Access 97, применяемые при отладке программ. Перейдем теперь к рассмотрению одного из алгоритмов, используемых при отладке программ. Это алгоритм локализации с точками останова.
Если Вы не знаете, как выполняется Ваша программа, например, если в результате ошибок в программе выполняется не тот оператор, либо происходит переход не на ту точку, можно воспользоваться описанной выше процедурой отладки с некоторыми изменениями.
На шаге 1 выберите несколько возможных точек останова; то же сделайте на шаге 2. Кроме того, на шаге 2 удалите все точки останова, до которых, по Вашему убеждению, программа не дойдет, когда Вы ее запустите на шаге 3. Далее следите не только за содержимым памяти (значениями переменных), но и за тем, на какую точку останова вышла программа, чтобы убедиться, что это есть запланированная в данном случае точка останова.
Итак, локализация с точками останова используется для программ, слишком больших для отладки с помощью пошагового выполнения и трассировки. Для еще более длинных программ используется так называемый принцип разрыва телефонной линии, к описанию алгоритма которого мы и приступаем.
Установите первую точку останова где-то в середине программы. Когда программа выполнится до этого места (если это произойдет), проверьте содержимое памяти, чтобы убедиться, что программа до этого места работала правильно. Если это так, то Вы будете знать, что Ваша первая ошибка находится во второй половине программы. В противном случае она в первой половине.
Так или иначе, Вы сократили область поиска ошибки до половины программы. Теперь установите точку останова приблизительно в середине этой половины, снова запустите программу и проверьте содержимое памяти. Таким образом, Вы локализуете ошибку на участке в четверть программы. Продолжайте процедуру, деля программу каждый раз приблизительно пополам, пока Вы не сократите область поиска ошибки до таких размеров, при которых можно воспользоваться обычной методикой отладки с точками останова.
Если ошибки в программе приводят к неправильному порядку выполнения программных строк, предложенный метод следует, как и ранее, несколько изменить.
Может, например, получиться, что Вы установили точку останова в середине некоторого участка программы, но при выполнении программа проходит вообще мимо точки останова. Конечно, это все же локализует ошибку: она в первой половине этого участка. Однако Вы всегда можете установить несколько точек останова, как и при обычной отладке с точками останова.
От переводчика: я наткнулся на эту статью случайно, когда искал информацию по управлению загрузкой символов во время отладки. И хотя по этому вопросу информации было не так много, я с удовольствием прочитал всю статью. Большая часть были мне известна и до этого, но не всё. Уверен, что многие найдут в ней для себя что-то полезное. Статья написана полтора года назад, однако не все переходят на новые версии студии и сопутствующих инструментов сразу после их появления, так что актуальности статья не потеряла.
Баги встречаются на двух этапах жизненного цикла кода: во время разработки и в продакшене. Часто ошибки, которые вылезают в течение 10-15 минут с момента написания кода, мы даже не считаем за баги – они просто часть процесса написания кода. А багами мы гораздо чаще называем проблемы, которые проявляются в продакшене или при тестировании кода, написанного несколько дней назад; вероятно потому, что их сложнее отловить (код уже успел подзабыться). В любом случае, если код не делает того, что должен, это баг и его нужно отловить и исправить.
4 столпа эффективной отладки
Использование точек останова
Многие разработчики не знают всех возможностей отладки в Visual Studio, потому что отладка «и так работает». Например, хотя каждый VS-разработчик знаком с точками останова, многие не знают, что можно сделать в окне Breakpoints.
Чтобы открыть окно Breakpoins, выберите Debug | Windows | Breakpoints; в окне отобразится список всех установленных вами точек останова. Если вы не уверены, какая точка какой строке кода соответствует, просто кликните по ней двойным кликом и в редакторе откроется связанный с ней код.
Другая возможность диалога When Hit позволяет задавать, должно ли останавливаться выполнение программы на точке останова. Если выбрать остановку, то вы увидите каждое сообщение в момент его создания; в противном случае вы сможете просмотреть все сообщения после выполнения программы.
Если вы хотите остановить выполнение только при определенном условии, вы можете выбрать опции Condition или Hit Count. Опция Condition позволяет задать логическое условие, при котором произойдет остановка (например, Position > 30). Также можно выполнить остановку, если одна из переменных изменилась с момента последней остановки. Опция Hit Count прерывает выполнение только если точка останова сработала в n-й раз (или каждые n раз). Это особенно полезно, когда вам нужно остановиться где-то в конце цикла.
Между прочим, мой опыт говорит, что если в какой-то части приложения возникли проблемы, они продолжат там возникать. Если ваш опыт говорит о том же, вам понравятся дополнительные возможности Visual Studio 2010. Вы можете дать точкам останова названия, чтобы не забыть, для чего нужна каждая из них, и экспортировать их в XML-файл. В следующий раз, когда они вам понадобятся, вы можете импортировать их и начать отладку. Импорт/экспорт можно сделать с помощью тулбара вверху окна Breakpoints.
Показ и пропуск кода
В любой версии Visual Studio, в пункте Debug | General диалога настроек вы можете выбрать опцию Just My Code и перестать видеть код, который вы не писали. Если впоследствии вам понадобится это отключить (например, если где-то в сгенерированном коде возникает исключение), вы можете это сделать, выбрав Options and Settings в меню Debug (этот пункт есть только в VS2010 – прим. перев).
Чтобы выбрать конкретную сборку (или если вы используете VS2008), в режиме остановки процесса отладки откройте окно Modules и в списке DLL, загруженных вашим приложением, кликните правым кликом на нужной DLL и выберите Load Modules, чтобы загрузить символы для этой DLL. Конечно, подождать всё равно придется, но уже не так долго.
Я один из тех, кто пишет в свойствах полезный код и хочет иметь возможность пошагово их отладить. Начиная с VS2008SP1, появилась опция (Step over properties and operators), выключающая пошаговую отладку свойств и операторов. И в VS2010 она по умолчанию включена, так что вам может понадобиться ее выключить.
Визуализация данных
Как ни странно, множество разработчиков не знакомы с визуализаторами данных в Visual Studio. Если в режиме остановки навести мышку на переменную, всплывет подсказка со значением этой переменной. Также может появиться значок с лупой – клик по нему откроет значение переменной в визуализаторе по умолчанию. Если рядом с иконкой появляется стрелка выпадающего списка, клик по стрелке покажет другие визуализаторы для этого типа данных. Например, для строковой переменной будут показаны текстовый, XML и HTML визуализаторы. Если вы храните в строке HTML, HTML-визуализатор позволит понять, как это будет выглядеть в браузере.
Визуализаторы вы можете также использовать в окнах Watch, Autos и Locals, но если вы смотрите какую-то переменную очень часто, вы можете нажать на канцелярскую кнопку в конце всплывающей подсказки, чтобы «пригвоздить» ее на этом месте. Тогда в следующий раз, когда вы будете просматривать эту часть кода, подсказка всплывет автоматически.
Кстати о подсказках – вы можете с их помощью менять значение переменной. В VS2010 даже более того: подсказку можно заставить висеть в окне, существовать всё время сеанса отладки, и даже после его окончания она будет отображать значение переменной из последнего сеанса. Однако, самые крутые инструменты (Debugger Canvas и IntelliTrace) доступны только в VS2010 Ultimate Edition.
Редактор в студии позволяет смотреть только на один участок кода в один момент времени. Но множество багов возникает в результате взаимодействия между разными частями кода. Debugger Canvas позволяет вам увидеть весь ваш код разом, перемещаясь между модулями и приближая нужную часть.
Когда срабатывает точка останова, вам нужно понять, как вы здесь оказались. Можно использовать окно Call Stack, но вы не увидите, что происходило на более ранних этапах (как вариант, можно поставить кучу точек останова и проходить их последовательно, отслеживая переменные).
Если Debugger Canvas позволяет смотреть «через модули», то IntelliTrace – «через время», что дает понимание того, как вы попали в данную точку останова. IntelliTrace собирает и показывает отладочную информацию, которая была доступна в предыдущие моменты времени сеанса отладки.
Еще лучше Debugger Canvas и IntelliTrace работают в связке: в Debugger Canvas есть опция, позволяющая видеть логи IntelliTrace рядом с кодом.
Внешние инструменты
Visual Studio – не единственный инструмент отладки, есть сколько угодно внешних и сторонних инструментов, которые вы можете добавить в копилку. Я здесь остановлюсь только на некоторых бесплатных.
Не все внешние инструменты сделаны сторонними производителями. Если вы пишете службы Windows, то знаете, что отлаживать их непростое занятие. Хотя вы и можете подключиться к ним для отладки, к этому времени код OnStart и инициализация уже выполнится. Если баг не дает сервису запуститься, вам остается только гадать, что же пошло не так, вместо того чтобы собрать информацию для описания проблемы.
В подобной ситуации вы можете настроить Just-in-Time (JIT) отладку и автозапуск – сеанс отладки начнется, когда служба запустится или когда возникнет ошибка. Но чтобы это сделать, вам нужно воспользоваться внешними инструментами.
Так как настройка JIT-отладки выходит за рамки данной статьи, вы можете обратиться к соответствующей статье в MSDN. Эта статья советует использовать Global Flags Editor (gflags.exe); на случай, если вы не можете его найти, описывается, как подправить реестр, чтобы включить JIT-отладку. Однако вам придется научиться пользоваться WinDbg.
Сторонние визуализаторы
Я уже говорил про визуализаторы Visual Studio, но есть еще множество сторонних. DotNetDan’s DataSet Visualizer – весьма чудесен, если вам нужно знать, что лежит в датасете (я упоминал его в блоге)
С того времени я уже обнаружил RightHand DataSet Visualizer и стал использовать его. Это MDI-приложение, которое позволяет открыть окно для каждой таблицы датасета. Кроме того, окно Relations показывает таблицы, связанные с текущей просматриваемой.
Грид, отображающий таблицу, не простой – вы можете перетащить колонку в прямоугольник вверху окна, чтобы группировать вашу таблицу по этой колонке. Также можно изменять данные в датасете и менять фильтр RowState, чтобы отображались только строки с определенным RowState (например, только удаленные). Еще можно смотреть (и менять) некоторые свойства датасета. И даже можно выгрузить датасет в XML-файл или загрузить тестовые данные из сохраненного ранее.
Следует отметить, что DotNetDan’s DataSet Visualizer быстрее загружает данные, так что я оставил его на случай, когда не нужна вся мощь RightHand.
Еще есть Web Visualizer для приложений ASP.NET. Этот визуализатор доступен на всплывающей подсказке любого объекта страницы ASP.NET (включая Me и this в коде ASP.NET)
С помощью Web визуализатора можно смотреть любые данные коллекции Server Variables объекта Server и коллекции Forms объекта Request. Также можно посмотреть строку запроса браузера и содержимое объектов Session и Application. Однако, в случае Session и Application для любых объектов, кроме скалярных данных, вы увидите только название типа объекта.
Есть и другие визуализаторы, включая те, что позволяют смотреть Cache и LINQ-запросы к Entity Framework (EF), а также позволяющие увидеть SQL на выходе LINQ-запросов к EF. Печально только то, что нет единого каталога визуализаторов.
Не все, но многие можно найти через Visual Studio Extension Manager. В том числе, ASP.NET MVC Routing Visualizer. Если вы используете маршрутизацию в ASP.NET MVC или в простом ASP.NET, вам пригодится этот инструмент. Взаимодействие между правилами маршрутизации может выдавать неожиданные результаты («Почему я получаю эту страницу?»), и отладка этих правил может быть непростой. Визуализатор позволяет вам ввести URLы и посмотреть, как маршрутизатор их декодирует, включая информацию о том, какое правило используется для каждого URL. Чтобы использовать его в режиме останова, переключитесь на ваш файл global.asax и наведите курсор на RouteTable. Когдя появится всплывающая подсказка, промотайте до коллекции Routes и кликните на значок лупы.
Трассировка
Трассировка по определению непривлекательна. Однако когда в продакшене вы нарываетесь на один из неуловимых багов, которые сложно повторить (и которые появляются и исчезают сами по себе), трассировка – единственный путь получить нужную информацию. Для этого, во-первых, вам нужно организовать запись сообщений в лог, который даст вам информацию для поимки бага. Но чтобы эта информация стала полезной, нужен инструмент для анализа содержимого лога.
Когда дело доходит до чтения полученных логов, я использую Log Parser Lizard от Lizard Labs. В бесплатной версии некоторые возможности ограничены (цена платной – около 25$), однако мне они ни разу не понадобились. Log Parser Lizard использует SQL-подобный синтаксис для построения запросов к логам (включая файлы формата CSV и XML) и прямо из коробки понимает форматы логов IIS, событий Windows и log4net. Результаты отображаются в таблице, что делает его похожим на Server Explorer, с которым мне очень нравится работать.
Средства получения справки и отладки программ
Окно контрольных значений (Watches)
Это окно используется для отслеживания значений переменных или выражений. Можно одновременно задавать несколько контрольных выражений. Можно использовать контрольные значения для задания моментов останова программы.
Определяемое пользователем контрольное выражение позволяет следить в процессе пошагового выполнения программы за изменением значения этого выражения.
Чтобы определить новое контрольное выражение, выполните команду Add Watch (Добавить контрольное значение) из меню Debug. Кнопка панели инструментов
Вводимое в строку Expression (см. рис. 3.12) выражение может быть переменной, свойством или любым другим допустимым в Visual Basic выражением. Если в окне модуля перед выполнением команды Add Watch было выделено некоторое выражение, то оно автоматически отображается в строке Expression.
Допускается перетаскивание мышью выделенного выражения из окна модуля в окно контрольных значений Watches.
Поле Module отображает имя модуля, в котором вычисляется выражение. Допускается выбор всех модулей либо отдельного модуля.
Строка Project отображает имя текущего проекта. Вычисление выражений вне текущего проекта невозможно.
В области Watch Type (Тип контрольного значения) можно задать реакцию Visual Basic на значение контрольного выражения:
Введенное выражение и его значение отображаются в окне Watches ( рис. 3.13).
Команда Edit Watch (Изменить контрольное значение) из меню Debug позволяет отредактировать или удалить контрольное выражение.
Команда доступна только при установленном контрольном значении, даже если окно контрольных значений закрыто.
Окно диалога Edit Watch ( рис. 3.14)похоже на окно Add Watch и элементы окна Edit Watch устанавливаются точно также как элементы окна Add Watch. Кнопка панели инструментов
Команда Quick Watch (Контрольное значение) из меню Debug выводит окно диалога Quick Watch с текущим значением выделенного в тексте процедуры выражения. Эта команда служит для просмотра текущего значения переменной, свойства объекта или другого выражения, для которого не задано контрольное выражение.
Для добавления просматриваемого в окне Quick Watch ( рис. 3.15) выражения в список контрольных выражений следует нажать кнопку Add. Кнопка панели инструментов
Контрольные точки или точки останова
Точка останова ( Breakpoint ) представляет собой строку процедуры, на которой разработчик во время отладки планирует остановить выполнение программы. Обычно точки останова используются в больших программах с целью определения их поведения. Имеет смысл устанавливать контрольные точки там, где предположительно может возникнуть ошибка, или в местах, которые отмечают прохождение логических частей программы, например, окончание ввода данных, расчет промежуточных результатов и т.п.
Для установки контрольной точки переместитесь на нужную строку процедуры и нажмите пиктограмму
Если точка останова задана в строке, содержащей несколько операторов, разделенных двоеточием (:), останов происходит в первой инструкции такой строки.
Если точки останова больше не нужны, их надо снять. Отмена всех точек останова производится командой Clear All Breakpoints (Снять все точки останова) из меню Debug или клавишами Ctrl+Shift+F9. Отменить действие этой команды нельзя.
Для снятия одной точки останова выполните команду Toggle Breakpoint из меню Debug для строки процедуры, содержащей точку останова. Можно нажать клавишу F9 или пиктограмму
Трассировка или пошаговое выполнение программы
| Команда | Пиктограмма | Клавиша | Описание |
|---|---|---|---|
| Step Into Шаг с заходом | | F8 | Последовательное выполнение всех строк программы (вызывающей и вызываемой процедур) |
| Step Over Шаг с обходом | | Shift+F8 | Выполнение вызываемой процедуры как одной инструкции. Используется для продвижения по командам вызывающей процедуры без захода внутрь вызываемых процедур |
| Step Out Шаг с выходом | | Ctrl+Shift+F8 | Выполнение оставшейся части вызываемой процедуры как одной инструкции с выходом на оператор вызывающей процедуры, непосредственно следующий за вызовом процедуры |
| Run to Cursor Выполнить до текущей позиции | | Ctrl+F8 | Выбор оператора останова программы. Используется для продвижения по логическим разделам программы, например, по большим циклам |
| Set next Statement Задать следующую инструкцию | | Ctrl+F9 | Изменение порядка выполнения операторов. Используется для повтора команд внутри текущей процедуры, а также для пропуска нежелательных операторов. Достаточно переместить точку вставки на нужную инструкцию и нажать эту пиктограмму. Можно переместить указатель выполняемого оператора (стрелка слева) в нужную строку процедуры. Допускается выбор строки программы, расположенной как до, так и после текущего оператора. Нельзя задать в качестве следующей выполняемой команды оператор в другой процедуре |
| Show next Statement Показать следующую инструкцию | Перечисленные команды доступны только в режиме отладки. Использование объекта DebugОбъект Debug используется для организации вывода в окно Immediate в режиме выполнения программы. Объект имеет только один метод Print. Синтаксис оператора Debug.Print [outputlist] Для печати нескольких выражений их можно разделять запятой, точкой с запятой или пробелом. Различные разделители обеспечивают различные возможности выравнивания распечатываемых выражений в окне Immediate (подробно см. Help ). Отладка и оптимизация программ. ОтладкаПривычное назначение окна Watch в той или иной среде программирования состоит в том, что оно является окном наблюдений и позволяет следить за состоянием некоторых переменных и выражений программы. Теперь, во многом, эта функция перешла к окну Locals. Тем не менее, и окно Watch используется для этой же цели. В отличие от окна Locals, выражения, появляющиеся в этом окне, не связаны с контекстом выполняемой процедуры. Программист сам формирует список наблюдаемых переменных и выражений, при этом всегда можно точно указать область определения наблюдаемой переменной. Следует только понимать, что злоупотреблять контрольными выражениями не следует, поскольку они замедляют процесс вычислений, поскольку перевычисляются на каждом шаге. Кроме того, по этой же причине следует аккуратно задавать контекст, в котором следует вычислять эти выражения. Помимо окна Watch, в котором появляются контрольные выражения, есть еще окно для добавления нового контрольного выражения, напомним, это окно может быть вызвано соответствующей инструментальной кнопкой панели Debug или, чаще всего, командой Add Watch из контекстного меню, появляющегося при нажатии правой кнопки в окне кода. Вот как выглядит это окно: Щелкнув по кнопке Add в этом окне, мы добавили переменную MyDict в окно Watch. Сравнивая окно Watch с окном Locals, отметим, что к трем колонкам Expression, Value и Type добавился еще один столбец Context, в котором задается контекст контрольного выражения. Взгляните, как выглядят эти окна после того, как мы добавили три контрольных выражения: Еще один вид информации о текущем состоянии вычисления представлен стеком вызовов процедур. Имя каждой вызванной процедуры помещается на вершину этого стека в момент ее вызова и убирается из него сразу после завершения этого вызова. Просмотреть стек вызовов можно, нажав клавиши Ctrl+L или выбрав инструментальную кнопку или команду » Call Stack …» в меню View. Чаще всего, в окно «Стек вызова» попадают из окна Locals, щелкнув в нем имеющуюся для этой цели кнопку «…». Заметьте, полученной информации достаточно, чтобы понять в какой процедуре произошло изменение значения переменной info. Но эта процедура рекурсивна и вызывалась неоднократно. Поэтому хотелось бы знать, на каком шаге ее вызова произошло изменение контрольной переменной. Для этого и служит стек вызовов, окно которого и было открыто щелчком соответствующей кнопки в окне Locals. Не пропустите наши новые статьи: Подписаться авторизуйтесь 0 комментариев Старые |


















