Сообщений 0 Оценка 60 Оценить |
Общие принципы отладки DLL Отладка расширений оболочки Windows Отладка Add-in'ов к Visual C++ Отладка ISAPI-расширений |
Хотя в виде DLL реализуются самые различные объекты, существует 2 общих принципа отладки, применимых ко всем разновидностям DLL.
Дальнейшая отладка DLL ничем принципиально не отличается от отладки приложений.
Иногда приложение, использующее DLL, само должно запускаться ещё одним приложением (именно такая ситуация имеет место с ISAPI-расширениями, которые загружает сервис IIS). В этом случае можно придерживаться следующей тактики.
Для расширений оболочки Windows в качестве отлаживаемого приложения указывается explorer.exe.
Поскольку в системе не могут работать две оболочки одновременно (об исключениях из этого правила мы поговорим немного позже), необходимо завершить оболочку Windows, прежде чем запускать новую из-под отладчика. Чтобы завершить оболочку, нужно:
ПРИМЕЧАНИЕ В Windows 2000 вместо кнопки No следует щёлкнуть по кнопке Cancel. |
Чтобы снова запустить оболочку по окончании сеанса отладки, достаточно запустить explorer.exe из любой оболочки или из командной строки. Если ни оболочки, ни командной строки под рукой нет, можно использовать следующие приёмы.
Под Windows NT/2000:
Под Windows 9x:
В Windows NT/2000 можно запускать каждый новый экземпляр Проводника (Windows Explorer) в отдельном процессе (по умолчанию рабочий стол, панель задач и все Проводники запускаются в отдельных потоках одного процесса Explorer.exe). Благодаря этому можно обойтись без постоянных перезапусков оболочки. Чтобы включить этот режим работы оболочки, необходимо открыть в редакторе реестра ключ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer, добавить в него параметр DesktopProcess (типа REG_DWORD) и назначить ему значение "1". Изменения вступят в силу после выхода и повторного входа в систему.
В обычном режиме работы оболочка выгружает DLL не сразу, а по истечении некоторого промежутка времени. Это может помешать линкеру перезаписывать файл DLL. Чтобы оболочка выгружала DLL немедленно, нужно создать в реестре ключ HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\AlwaysUnloadDLL и записать "1" в его параметр по умолчанию.
При отладке add-in'ов отладчику Visual C++ приходится отлаживать самого себя. Лучше всего запустить экземпляр среды Visual C++ без add-in'а, а затем использовать этот экземпляр для отладки. Иначе возможны весьма тонкие и неочевидные ошибки, на исправление которых уйдёт уйма времени. Другая возможность для отладки add-in'ов – удалённая отладка (о ней мы поговорим в следующем разделе).
ПРИМЕЧАНИЕ Данные в этом разделе относятся к IIS5 |
ISAPI-расширение – это DLL, которая загружается веб-сервером IIS для обработки запросов. В зависимости от настроек защиты веб-приложения (application protection) они могут загружаться как главным файлом IIS inetinfo.exe (режим Low (IIS Process)), так и отдельным процессом dllhost.exe (режимы Medium (Pooled) и High (Isolated)). Чуть позже мы увидим, как отлаживать ISAPI-расширение в том и в другом случае. Но сначала несколько слов о подготовке расширения к отладке.
Прежде чем начинать отладку, рекомендуется проделать следующие шаги.
В MSDN упоминается альтернативный способ отключить кэширование: открыть в редакторе реестра ключ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters и добавить в него параметр (REG_DWORD)CacheExtensions=0. Но мне не удалось заставить этот метод работать. |
Если веб-сервер ещё не запущен, запустите его. После этого можно переходить непосредственно к отладке.
В процессе отладки ISAPI-расширений довольно часто приходится запускать и останавливать веб-сервер. Для этого можно использовать команды net start w3svc и net stop w3svc соответственно. При желании можно добавить эти команды в меню Tools, чтобы они всегда были под рукой. |
В этом режиме DLL загружается процессом inetinfo.exe. Чтобы к нему присоединиться, можно использовать любую из описанных в предыдущем разделе методик (команду Attach To Process, команду Debug в Task Manager или функцию DebugBreak, которую в данном случае следует вставить в GetExtensionVersion расширения). После этого можно действовать по сценарию, описанному в подразделе "Общие принципы отладки", чтобы загрузить отладочные символы (если это необходимо) и расставить точки останова.
Чтобы DLL получила управление, необходимо послать ей запрос. Это можно сделать из Internet Explorer. Запрос будет выглядеть примерно так: http://localhost/test/MyISAPI.dll.
Если объем отладки велик, и часто приходится запускать и останавливать сервис, проще запускать IIS из отладчика, как обыкновенное приложение.
Чтобы заставить IIS работать в таком режиме, нужно изменить учетную запись, под которой запускаются сервисы IIS Admin, World Wide Web Publishing и FTP Publishing, на запись, под которой будет производится отладка. Физически при запуске всех этих сервисов запускается один и тот же исполняемый файл – inetinfo.exe. DLL-библиотеки загружаются в сервис World Wide Web Publishing, но он зависит от IIS Admin-сервиса, поэтому сервис IIS Admin должен быть запущен первым. Учетная запись, под которой теперь будут запускаться сервисы, должна иметь довольно высокие привилегии. Проще всего использовать для этого учетную запись администратора, добавив ей привилегию "Act as part of the operating system" (программистам известную как SE_TCB_NAME). Будьте осторожны, так как эта привилегия предоставляет широчайшие возможности. Теперь нужно настроить отладчик Visual C++, задав в качестве отлаживаемого проекта путь к файлу inetinfo.exe (по умолчанию он размещается в каталоге %SystemRoot%\System32\inetsrv\), а в качестве параметров строку "-e w3svc". Теперь при запуске проекта на отладку IIS будет загружаться автоматически. В начале очередного сеанса отладки не помешает убедиться, что сервис World Wide Web Publishing не был загружен именно как сервис (например, при перезагрузке системы).
В этом режиме DLL загружается процессом dllhost.exe. Процесс отладки для него ничем принципиально не отличается от предыдущего случая. Помните только, что метод подключения к процессу с помощью DebugBreak не будет работать, так как исключение EXCEPTION_BREAKPOINT будет перехвачено внутри dllhost.exe.
В системе может быть несколько процессов с именем dllhost.exe. Необходимо выяснить, какой из них загружает DLL-расширения. Сделать это можно различными способами. Один из возможных вариантов – вставить в саму DLL код, сообщающий идентификатор процесса, в который она загружена. Например:
#define _WIN32_WINNT 0x0400 #include <windows.h> ... #ifdef _DEBUG TCHAR szMessage [256]; _stprintf( szMessage, _T("Please attach a debbuger to the process %u and click OK"), GetCurrentProcessId() ); MessageBox(NULL, szMessage, _T("ISAPI debugging"), MB_OK|MB_SERVICE_NOTIFICATION); #endif |
Обратите внимание на флаг MB_SERVICE_NOTIFICATION. Он необходим, чтобы сообщение из ISAPI-расширения было видно на экране.
Сообщений 0 Оценка 60 Оценить |