Образец EEAddIn: надстройка вычислителя выражений для отладки
Обновлен: Ноябрь 2007
В образце EEAddin показано, как расширить собственный вычислитель выражений отладчика, используя API надстройки вычислителя выражений.
Примечание о безопасности. |
---|
Этот образец кода служит для демонстрации основных принципов и не предназначен для использования в приложениях или на веб-узлах, поскольку не может считаться примером наиболее безопасного кода. Корпорация Майкрософт не несет ответственности за случайные или косвенные убытки в случае использования образца кода не по назначению. |
Чтобы получить образцы и инструкции по их установке, выполните следующие действия.
В меню Справка среды Visual Studio выберите пункт Примеры.
Дополнительные сведения см. в разделе Поиск файлов примеров.
Самая последняя версия и полный список образцов доступны в Интернете на странице образцов Visual Studio 2008.
Кроме того, образцы находятся на жестком диске компьютера. По умолчанию образцы кода и файл Readme копируются в папку, находящуюся в папке \Program Files\Visual Studio 9.0\Samples\. Все образцы кода для экспресс-выпусков Visual Studio находятся в Интернете.
API надстройки вычислителя выражений
Вычислитель выражений — это компонент отладчика, который интерпретирует (вычисляет) выражения. Если задать точку останова на выражении или ввести выражение в окне отладчика, вычислитель выражений интерпретирует введенные данные. Дополнительные сведения см. в разделе Выражения в отладчике. С помощью API надстройки вычислителя выражений можно расширять возможности вычислителя выражений, дополняя их поддержкой обработки новых типов.
Чтобы дополнить вычислитель выражений поддержкой нового типа, необходимо создать функцию в составе DLL-библиотеки Win32 (в том же каталоге, где находится autoexp.dat) и экспортировать ее по имени. Необходимо также добавить строку в файл autoexp.dat. Вычислитель выражений можно дополнить поддержкой более чем одного типа, экспортируя несколько функций из библиотеки DLL.
Построение и запуск образца
Процедура построения и запуска данного образца состоит из трех частей.
Построение и запуск образца
Постройте библиотеку DLL надстройки вычислителя выражений (eeaddin.dll).
Измените файл autoexp.dat, разрешив в нем использование библиотеки DLL надстройки вычислителя выражений.
Протестируйте надстройку, создав проект с пользовательским типом данных, вычисляемым с помощью autoexp.dat.
Эти шаги подробно описываются в следующих процедурах.
Построение библиотеки DLL надстройки вычислителя выражений
Откройте в Visual Studio решение eeaddin.sln.
В меню Построение выберите команду Построить.
Скопируйте результирующий файл eeaddin.dll в каталог common7\ide (где находится файл devenv.exe).
В меню Файл выберите команду Закрыть решение.
Изменение файла autoexp.dat
В меню Файл выделите команду Открыть и выберите пункт Файл.
В диалоговом окне Открытие файла найдите файл autoexp.dat (в каталоге common7\packages\debugger) и нажмите кнопку Открыть.
Измените файл autoexp.dat, добавив в него следующие строки:
_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime@28) _FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime@28)
Сохраните файл autoexp.dat.
Создание проекта с пользовательскими типами данных
В меню Файл выделите команду New и выберите пункт Проект.
В диалоговом окне Создать проект выделите Проекты Visual C++, щелкните Приложение MFC, введите имя для проекта и нажмите кнопку ОК.
В окне Мастер приложений MFC нажмите кнопку Готово. Проект должен быть приложением MFC, поскольку на следующем шаге в него будут добавляться функции MFC.
В приложении MFC добавьте объект SYSTEMTIME или FILETIME.
SYSTEMTIME *s = new SYSTEMTIME(); FILETIME *f = new FILETIME(); GetSystemTime(s); SystemTimeToFileTime(s,f);
В меню Построение выберите команду Построить.
Начните отладку, наблюдая за объектом SYSTEMTIME или FILETIME в окне контрольных значений.
Принцип работы образца
Для расширения вычислителя выражений за счет пользовательского типа данных в библиотеке DLL надстройки вычислителя выражений создается функция просмотра. Эта функция использует указатель на объект, находящийся в пространстве памяти отлаживаемой программы (а не в памяти расширяемого вычислителя выражений). Для этого указателя нельзя использовать обычное приведение типов. Необходимо считывать его и указываемые им данные, используя функцию обратного вызова. Указатель обратного вызова типа DEBUGHELPER* указывает на объект различными методами.
Синтаксис выглядит следующим образом.
HRESULT WINAPI CustomViewer(
DWORD dwAddress, // low 32-bits of address
DEBUGHELPER *pHelper, // callback pointer to access helper functions
int nBase, // decimal or hex
BOOL bIgnore, // not used
char *pResult, // where the result needs to go
size_t max, // how large the above buffer is
DWORD dwReserved // always pass zero
)
Образец включает две реализации функции этого типа: AddIn_SystemTime и AddIn_FileTime, содержащиеся в файле timeaddin.cpp. Структура DEBUGHELPER (определенная в файле custview.h) состоит из указателей функций, которые могут быть полезны при создании данного расширения. Такой указатель передается в функцию CustomViewer, и его можно использовать для вызова вспомогательных функций.
Получить тип процессора можно с помощью функции pHelper->GetProcessorType. Предусмотрены два метода чтения памяти: pHelper->ReadDebuggeeMemory и pHelper->ReadDebuggeeMemoryEx. Метод ReadDebuggeeMemoryEx обрабатывает 64-разрядные адреса и поддерживается отладчиком Visual Studio .NET. Метод ReadDebuggeeMemory не обрабатывает 64-разрядные адреса и поддерживается отладчиками Visual Studio .NET и Visual C++ 6.0. Если надстройка предназначается только для отладчика Visual Studio .NET, можно использовать ReadDebuggeeMemoryEx. Если надстройка должна работать и с отладчиком Visual C++ 6.0, необходимо проверить поле dwVersion и не вызывать ReadDebuggeeMemoryEx для Visual C++ 6.0.
Следующий код работает с обоими отладчиками; в нем считывается содержимое объекта localobject (относящегося к типу MyType) из отлаживаемой программы:
DWORDLONG qwRealAddress;
DWORD dwGot;
MyType localobject;
if (pHelper->dwVersion<0x20000)
{
// Visual C++ 6.0 version
qwRealAddress = dwAddress;
pHelper->ReadDebuggeeMemory( pHelper, dwAddress,
sizeof(localobject), &localobject, &dwGot );
}
else
{
qwRealAddress = pHelper->GetRealAddress(pHelper);
pHelper->ReadDebuggeeMemoryEx( pHelper, qwRealAddress,
sizeof(localobject), &localobject, &dwGot );
}
// TODO: display localobject here
Изменение файла autoexp.dat
Строки, добавляемые в раздел [AutoExpand] файла autoexp.dat, должны использовать следующий синтаксис:
type=$ADDIN(dllname.dll,exportname)
Например:
_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime)
или
_FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime)
Если библиотеки DLL нет в каталоге, содержащем файл devenv.exe, или в каталогах пути, заданного переменной PATH, необходимо указать для DLL полное имя пути. Аргумент exportname вводится с учетом регистра символов; он должен в точности совпадать с экспортированным именем, полученным при выполнении функции dumpbin –exports для библиотеки DLL.
Для тестирования отладчика с новой надстройкой сначала прекратите отладку всех программ, которые отлаживались в момент установки новой библиотеки DLL, а затем запустите новый сеанс отладчика.
Примечание. Надстройка выполняется в среде отладчика, поэтому аварийный сбой кода приведет к аварийному завершению IDE.