пятница, 17 августа 2007 г.

Установка брейкпоинтов в управляемом коде без исходников

Хочу поделиться простой техникой установки точек прерывания (breakpoints) на методах классов, к которым у вас нет исходных кодов.
Такой вариант использования брейкпоинтов может понадобиться, если у вас по каким-либо причинам нет исходных текстов компоненты или вас совершенно не интересует исходный код метода, а, скажем, только стек вызова этого метода. Таким образом, данная техника позволяет устанавливать точки прерывания на методах классов NET Framework или третьих фирм. Установка точек прерывания на ключевых методах кода позволяет быстро получить ответ на вопросы типа: почему был вызван некий метод, в какой момент происходит установка свойства, вызывался ли интересующий метод вообще. Такой техникой я обычно пользуюсь, когда нахожусь на стадии локализации проблемы и/или при проверке различных гипотез при отладке. Грамотная установка точек прерывания позволяет быстро узнать стек вызов для интересующего метода, чтобы в итоге понять, откуда у проблемы «ноги растут». Эта техника установки точек прерывания работает, как для Visual Studio 2003, так и для Visual Studio 2005. На других версиях среды разработки я не проверял, но, скорее всего, работает и там. Хочу еще раз подчеркнуть, что эта техника работает только для управляемого кода. Если есть необходимость работать с брейкпоинтами для неуправляемого кода, то лучше воспользоваться более мощным отладчиком, например WinDBG (http://www.microsoft.com/whdc/devtools/debugging/default.mspx), но это уже совсем другая история.
Далее рассмотрим пошагово, как устанавливать точки прерываний в Visual Studio 2003. Предположим, нас интересует, в какой момент у формы вызывается метод OnPaint для класса Form из пространства имен System.Windows.Forms. Особо не задумывайтесь над смыслом примера — он служит лишь для того, чтобы показать, как устанавливать точки прерывания.
Итак, создайте новый проект WindowsApplication (File -> NewProject -> Windows Application). Затем в главном меню Visual Studio выберите пункт Debug, в нем подпункт-меню Windows и, наконец, пункт Breakpoints. Откроется плавающее окно со списком точек прерывания (рис. 1).
Рис.1 – Главное окно Visual Studio 2003 с активированной панелью Breakpoints
На панели инструментов этого окна выберите команду New. Появится диалоговое окно для задания координат новой точки прерывания. Переключитесь на закладку Function и в поле ввода Function напишите полное имя функции, на которой будет устанавливаться точка прерывания, а в выпадающем списке Language выберите Unknown (рис. 2).


Рис. 2 – Диалоговое окно для установки новой точки прерывания

Все. Завершите установку новой точки прерывания, нажав кнопку OK.
В Visual Studio 2005 установка точки прерывания осуществляется точно так же. Дополнительно для Visual Studio 2005 надо убрать опцию Enable Just My Code. Откройте окно настроек студии Tools -> Options. В иерархическом списке настроек найдите и выделите узел Debugging и затем в списке General правой части окна сбросьте флаг Enable Just My Code (рис. 3).

Рис. 3 – Окно настроек Visual Studio 2005

Теперь можно запускать приложение на выполнение под отладкой (Debug -> Start Debugging).

После старта приложения отладчик остановит приложение на нашей точке прерывания. Студия выдаст предупреждение, что для этой точки прерывания она не смогла найти исходные коды, что вообще-то и ожидалось. Нажмите OK, либо Show Disassembly. Чтобы посмотреть стек вызовов, откройте окно Call Stack (Debug -> Windows -> Call Stack) (рис. 4).



Рис . 4 – Отладчик Visual Studio 2003 с активированной панелью Call Stack

Если стек показывается не полностью, а вместо некоторых имен функций выводится [Non user code], выделите строку с текстом [Non-user Code], вызовите контекстное меню и включите опцию Show Non-user Code.

И напоследок несколько полезных советов.

Чтобы задать точку прерывания, к примеру, на изменение свойства, надо поставить точку прерывания на его set –методе. Например, чтобы остановиться в отладчике в момент изменения свойства формы Text, в поле Function надо указать следующий текст:

System.Windows.Forms.Control.set_Text

Обратите внимание, что свойство Text определено на уровне класса Control из пространства имен System.Windows.Forms и именно его мы используем при создании новой точки для класса Form.
Чтобы установить брейкпоинт на вызове конструктора, например класса BitVector32, в качестве функции надо указать следующий текст:

System.Collections.Specialized.BitVector32.BitVector32
Небольшое замечание по поводу установки брейкпоинтов. Точка прерывания должна быть установлена до первого вызова метода, то есть до того, как будет выполнена его JIT-компиляция. Идеальный вариант – вообще до старта приложения. Для отладки простого приложения, как в примере, это тривиальная задача. Если же точку прерывания надо поставить при отладке компоненты, которая подключается к существующему приложению (хост-приложение), то задача немного усложняется. В этом случае можно поступить несколькими способами.

Во-первых, можно воспользоваться отладчиком DbgCLR.exe, который идет с .NET Framework SDK (у меня он находится здесь: C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\GuiDebug для .NET 1.1 и здесь С:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\GuiDebug для .NET 2.0). Установка точек прерывания и отладка в нем аналогична Visual Studio, но у него есть возможность указать приложение для отладки (Debug -> Program To Debug).

Во-вторых, при отладке приложений в Visual Studio можно для отлаживаемой компоненты указать, что для ее отладки будет запущено определенное приложение. Для этого открываете Solution Explorer и в контекстном меню проекта компоненты выбираете пункт Properties. В 2005 студии откроется закладка с именем проекта. Переключитесь на пункт Debug. Далее в группе Start Action выберите вариант Start external program и в поле справа укажите путь и имя хост-приложения (рис. 5).

Рис. 5 – Установка хост-приложения для отладки компоненты в Visual Studio 2005


Для 2003 студии откроется диалоговое окно настроек проекта. В иерархическом списке в левой части окна раскройте узел Configuration Properties и выберите пункт Debugging. В списке настроек (в правой части окна), в группе Start Action в пункте Debug Mode, установите значение Program. Нажмите кнопку Apply и после этого в пункте Start Application укажите путь и имя хост-приложения (рис. 6).


Рис. 6 – Установка хост-приложения для отладки компоненты в Visual Studio 2003

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