Неформальное введение в объектно-ориентированное программирование на платформе Net.Framework.

(с) Герман Иванов.

Статья шестая(фрагмент). Отладка приложений в Visual Studio Net.

В этой статье мы поговорим о том, как в Visual Studio происходит отладка приложений. Без ее использования мне будет трудно раскрыть вам темы поднимаемые в моих статьях. Давайте разберемся, как в Visual Studio создаются контрольные точки остановки (BreakPoints) программы, да и вообще происходит отладка приложений. Для начала давайте поговорим о том, что это вообще такое. Когда вы запускаете свою программу на выполнение, она очень быстро проскакивает через все команды, сразу выводя вам результат своей работы. Довольно часто получается так, что синтаксически правильный код работает вовсе не так, как вы ожидали.

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

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

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

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

1) Возможность остановить выполнение программы в любом произвольном месте(BreakPoint-точка остановки). Такая остановка может происходить либо при первом входе в указанный участок кода, либо при указанном вами очередном входе. К примеру, вы заметили, что ошибка возникает только при 256 вызове некоей функции. Ставите точку остановки на функцию и указываете, что хотите остановить выполнение программы во время 256 прохождения этого участка кода. Отладчик так и сделает, и вы легко обнаруживаете, что вместо того чтобы использовать в качестве числа - счетчика тип int, вы использовали System.Byte. Поэтому и происходит переполнение.

Еще одна разновидность точки остановки - это остановка по условию. К примеру, вы говорите, что останавливать выполнение программы, в этом месте, следует только тогда, когда значение переменной internalHasDocument в объекте MVD_Worker равняется true. Отладчик будет проскакивать без остановки эту точку, если данное условие не выполняется и сразу остановится, как только это условие совпадет.

2) Возможность посмотреть содержимое используемых в программе объектов. Для этой цели в большинстве отладчиков существует окно называющееся Watch. Суть его работы сводится вот к чему, вы указываете, в этом окне, что хотите узнать, чему сейчас равняются значения свойств того или иного объекта. После того как отладчик остановит выполнение программы, в этом окне будет показано текущее состояние указанных вами переменных. По мере того как вы выполняете программу по шагам, значения переменных, в этом окне, меняются, по-прежнему отражая их реальное значение, изменяемое методами вашей программы за время этих шагов.

3) Возможность изменить это самое содержимое переменных. Если вы заметили, что некоторая функция "падает", если передать ей, в качестве параметра, число четырнадцать, то вы можете, как правило, в том же самом окне Watch, вручную ввести это число, не дожидаясь момента, когда оно попадет туда своим естественным путем. Затем проходите подозрительную процедуру по шагам, провоцируя ее показать, какой именно фрагмент кода приводит к нежелательным для вас последствиям.

4) Возможность пройти подозрительный фрагмент программы "по шагам". "По шагам" означает по одной конструкции языка за ход. Вы делаете шаг и смотрите, в окне Watch, как изменилось содержимое переменных в программе. Затем делаете еще шаг и опять смотрите, что происходит. Таким образом, можно найти сбойный участок в вашем коде. К примеру, тот, в котором возникает "третья рука у работника MVD". Найдя этот участок, вы прекращаете отладку и исправляете ошибку. Снова запускаете программу и убеждаетесь в правильности неписанного правила гласящего, что последняя найденная ошибка в коде всегда, на самом деле, является предпоследней.

Большинство отладчиков поддерживают несколько разновидностей пошагового прохода. К примеру, можно идти пошагово по коду, заходя во внутренности методов всех встречных объектов, а можно считать их "черными ящиками" и внутрь не заходить. Можно одним скачком проскочить код до позиции под вашим курсором, а дальше идти по шагам. Возможностей очень много и описывать их можно долго.

5) Возможность продолжить обычное безостановочное выполнение программы. Убедившись, что ошибка кроется где-то в другом месте, вы можете запустить программу выполняться дальше, до следующей точки остановки или до своего логического конца. Чтобы точка остановки больше не путалась под ногами ее можно временно отключить или полностью убрать.

Давайте посмотрим, как эти отладочные возможности реализованы в среде Visual Studio Net.

1) Возможность поставить точку остановки.

В Visual Studio это можно сделать как минимум двумя способами. Во-первых, просто щелкнуть по левой границе окна с текстом вашего класса на нужной строчке. Обратите внимание, справа у нас имеется скроллер(полоска с бегунком), для того чтобы перемещаться по тексту документа, а слева также имеется некая серая полоса, размером с скроллер, но на ней ничего нет. Щелкните мышкой по этой серой полосе, на ней появится красный кружок, а линия кода напротив него также окрасится в красный цвет. Произошедшее означает, что вам удалось установить, наиболее простую разновидность, точки остановки. По достижению помеченного участка кода, выполнение программы будет немедленно остановлено. После этого вы сможете воспользоваться остальными отладочными возможностями среды Visual Studio. Если вам нужна более "умная" точка остановки, вызовите на нужной строчке кода контекстное меню с помощью правой кнопки мыши или же поставьте курсор на нужную строчку и вызовите пункт меню "Debug->New BreakPoint" (на худой конец просто нажмите Ctrl-B). На экране появится мастер, состоящий из четырех закладок. Вы можете воспользоваться любой из них. Как только вы выставите желаемые значения на одной закладке, остальные автоматически заполняются, на основании тех данных, что вы указали.

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

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

Следующие две закладки относятся к более "низкоуровневой" отладке при программировании на языке "С++" без использования Net.Framework. Крайне маловероятно, что вы станете ими пользоваться при написании программ на C#. На третьей закладке вам предлагают установить точку остановки на конкретный физический адрес в вашем коде, а на четвертой, на факт изменения каких либо физических данных в вашем коде. Что любопытно, четвертой закладкой мне так воспользоваться и не удалось. На любые мои попытки установить такую точку остановки, выводится окошко, что Net.Framework не поддерживает такой метод. По всей видимости, этот режим предназначен исключительно для C++ и неуправляемого кода.

Прикол! Если добиться вывода сообщения о невозможности такого метода, а затем все-таки установить точку остановки с помощью второй закладки, то при повторном входе в мастер, например через свойства точки остановки, он состоит уже не из четырех, а из трех страниц. Последняя страница исчезает. По всей видимости, это глюк используемой мной версии среды разработки "Visual Studio 2003 Final Beta".

Для всех четырех методов установки точек останова можно указать дополнительные условия. Так, нажав кнопку Condition, можно задать какое либо условие, например определенное значение переменной. Точка остановки сработает только тогда, когда это условие выполнится. Условие выражения станет равно true. Второй допустимый вариант срабатывания изменение результата этого условия. Например, раньше было true, а теперь стало false. Нужный вариант задается специальной галочкой. Под кнопкой Condition, находится кнопка HitCount. Это счетчик входов в точку остановки, с помощью его мы указываем, какой именно последовательный проход через точку нас интересует. Предлагается также несколько вариантов. Можно сказать, останавливаться всегда или по достижению определенного количества проходов.

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

Постановим, что механизм контрольных точек в Visual Studio находится на должной высоте.

2) Теперь давайте посмотрим, как Visual Studio позволяет нам контролировать содержимое используемых в программе объектов. После того как отладчик останавливается на точке остановки, вы увидите перед собой три окна просмотра содержимого объектов. Окна озаглавлены "Autos", "Local" и "Watch". Если вы их случайно закроете, то всегда можете достать обратно. Живут они в пункте меню "Debug->Window".

В окне "Autos" отладчик показывает содержимое тех объектов, которые упоминаются в коде текущей выполняемой и соседних с ней строчках кода. В окне "Local" отображаются все локальные, для этого участка кода, объекты. Окно "Watch" предназначено на тот случай, если вам мало первых двух окон. Вы можете вписать в него любой произвольный объект. Его содержимое будет отображаться в этом окне.

Все три окна отображают также и внутреннюю структуру объектов в иерархической древовидной форме. То есть, если в некоем объекте есть вложенный объект, то, щелкнув по плюсику рядом с его именем, вы можете углубиться и в его внутреннее устройство. Это очень удобное свойство окон Watch я широко использовал на первых порах, вместо справочника по объектам Net.Framework. С его помощью вы можете изучить то, как устроен изнутри, скажем, объект Dataset. Создали его экземпляр, поставили точку остановки на следующую строчку за его созданием, и изучайте его внутреннюю структуру в окне "Watch", сколько вам влезет. Действительно очень удобно, рекомендую.

Да вот еще, совсем забыл. Окон Watch может быть несколько, дополнительные окна открываются через "Debug->Window->Watch". Помимо обычных окон Watch существует еще и плавающее окно QuickWatch. В нем можно быстро набрать имя какого-либо объекта и его значение выведется в нижнем списке.

3) Возможность изменить это самое содержимое.

Все, перечисленные в предыдущем абзаце, окна позволяют не только просматривать, но и изменять значение объектов. Просто вводите в их свойства новое значение и все. Кроме этого существует еще и такое интересное окно как "Immediate". В нем вы можете ввести любую произвольную команду, которую отладчик передаст отлаживаемой программе. Скажем, вместо того чтобы лазить по деревьям в окне Watch, в поисках свойства hasDocument у объекта gai1, можно просто набрать в этом окне gai1.hasDocument=true и свойство будет присвоено. В этом окне работает технология Intellisense, подсказывающая вам имеющиеся методы и свойства набираемого объекта. Вообще, функциональность этого окна намного больше, чем простой просмотр-изменение значений переменных. Рассказывать о нем можно долго...

4) Возможность пройти подозрительный фрагмент программы "по шагам".

И тут Visual Studio поддерживает стандартный набор способов пошагового прохода. Сгруппированы они в пункте меню Debug. Имеется и способ "с заходом в функции" (Step Into - F11) и способ без такого "захода" (Step Over - F10). Также, дополнительно, имеется метод "пропустить до выхода из метода" (Step Out - Shift F11). Объяснять, на пальцах, что именно делает каждый из этих трех способов можно долго. Думаю, вам будет проще самим поиграться всеми тремя способами, и посмотреть чем они отличаются друг от друга. Также довольно прозрачно объясняют различия в их поведения иконки, расположенные напротив соответствующих пунктов меню. На них наглядно изображено как работает каждый способ пошагового прохода.

5) Возможность продолжить обычное безостановочное выполнение программы.

Разобравшись с глюком, вы можете продолжить безостановочное выполнение программы. Как принято в Visual Studio, вам для этого предоставляется как минимум две возможности. Во-первых, можно выбрать "Debug->Continue(F5)" и программа пойдет дальше, своим ходом, до тех пор, пока снова не наткнется на какую-либо другую точку остановки, или эту же самую точку повторно. Во-вторых, можно, в меню "Debug", щелкнуть по "DetachAll". В этом случае отладчик "отцепится" от вашего приложения и оно пойдет дальше, игнорируя все точки остановки в коде. Помимо продолжения выполнения программы, вы можете прервать ее ход, выбрав "Debug->Stop debbuging (Shift-F5)". В этом случае выполнение программы немедленно оборвется, и вы можете приступать к исправлению найденных ошибок.

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

 

Ссылки:


При перепечатке сохранение раздела "Ссылки" обязательно!!!