ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 14

Глава 11. Использование средств отладки Windows
В данной главе описываются средства TDW, которые дают вам доступ к информации Windows и позволяют делать следующее:
- регистрировать сообщения, принимаемые и передаваемые окнами вашей прикладной программы;
- просматривать глобальную динамически распределяемую область памяти:
- просматривать полный список модулей, загружаемых Windows (включая динамически компонуемые библиотеки DLL). 
Средства Windows
Отладку программ Windows поддерживают следующие средства:
- окно просмотра, окно сообщений Windows, в которых показываются сообщения, передоваемые из вашей программы в окна;
- в окне регистрации Log можно выводить три типа данных:
   a) сегменты данных в локальной динамически распределяемой области вашей программы;
   b) сегменты данных в глобальной динамически распределяемой области;
   c) полный список модулей, входящих в вашу программу, включая библиотеки динамической компоновки DLL. 
Регистрация сообщений Windows
Для отслеживания сообщений, передаваемых в окна вашей программы, выберите для открытия окна Windows Messages (Сообщения Windows) команду ViewіWindows (ОбзоріWindows). Это окно показывает вам сообщения, которые Windows передает в одно или более окон вашей
 программы. 
Окно Windows Messages состоит из трех областей: области выбора окна (верхняя слева), области класса сообщений (верхняя справа) и области сообщений (внизу). cообщения выводятся в области сообщений. 
   ЙН[ю]НННWindows messagesННННННННННННННННННН3НННННН[][]»
   єWindowproc wndproc±±±±±±±іLog±message±WM±PAINT±±±±±±±±±є
   є                         і                             є
   є                         і                             є
   є                         і                             є
   єДДДДДДДДДДДДДДДДДДДДДДДДДДІ°°°°°°°°°°°°°°°°°°°°°°°°°°є
   єHwnd:2214 wParam:0000 lParam:000000000 (000f) WM PAINT є
   ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННЅ
Рис. 11.1 Окно Windows Messages
Выбор окна
     ЪДДДДДДДДДДДДДї
     і Add...      і           Добавить
     і Remove      і           Отменить
     і Delete All  і           Удалить все
     АДДДДДДДДДДДДДЩ
Перед тем, как вы сможете регистрировать сообщения, нужно сначала указать, для какого окна регистрируются сообщения. Это можно сделать в левой верхней области - области выбора окна. Локальное меню области (которое активизируются с помощью клавиш Alt-F10)
 позволяет вам добавить окно, удалить окно, или отменить все выбранные окна. 
Добавление выбранного окна
Для добавления выбранного окна вы можете либо выбрать команду Add (Добавление) локального меню области выбора окна, либо начать ввод в этом окне. Любой из методов выводит следующее диалоговое окно: 
 Й[ю]НAdd window or handle to watchНННННННН»
 є Window identifiers                      є
 є                                         є
 є                                   OK    є
 є                                 ±±±±±±± є
 є                                         є
 є                                  Cancel є
 є                                 ±±±±±±± є
 є  (.) Window proc                        є
 є  ( ) Handle                      Help   є
 є                                 ±±±±±±± є
 є                                         є
 ИНННННННННННННННННННННННННННННННННННННННННЅ
Рис. 11.2 Диалоговое окно Add Window
Примечание: Ввод в данном окне первого значения устанавливает также класс сообщений в значение "Log all messages" ("Регистрация всех сообщений"). 
Вы можете ввести либо имя подпрограммы, которая обрабатывает сообщения для окна (выберите переключатель Window Proc) или значение-описатель (выберите переключатель Handle). Введите столько имен подпрограмм или значений описателей, сколько нужно для отсле
живания сообщений ваших окон. 
Легче всего указать окно по имени подпрограммы, которая обрабатывает его сообщения (например, WndProc), поскольку в любой момент после загрузки вашей программы вы можете ввести имя подпрограммы. 
Если вы предпочитаете использовать имя переменной-описателя, то первым шагом в программе должна быть строка, где этой переменной присваивается описатель. (Для пошагового выполнения программы используйте клавиши F7 или F8.) Если вы пытаетесь ввести имя пе
ременной до того, как пройдете строку с оператором присваивания, то TDW не сможет выбирать для нее сообщения. 
Отмена выбора окна
Для отмены выбора окна переместите курсор на элемент, затем либо выберите локальное меню и используйте команду Remove (Удалить), либо нажмите клавиши Del, Ctrl-Y или Ctrl-R. 
Чтобы отменить все окна, выберите в локальном меню команду Delete All (Удалить все). 
Задание класса сообщений и действия
Верхняя правая область - это область класса сообщений. Ее локальное меню идентично локальному меню области выбора окна и позволяет вам добавить класс сообщения, удалить класс сообщения или удалить все классы, которые вы добавили. 
ЪДДДДДДДДДДДДДї
і Add...      і           Добавить
і Remove      і           Отменить
і Delete All  і           Удалить все
АДДДДДДДДДДДДДЩ
Перед тем, как добавить в данной области класс сообщений, в области выбора окна нужно задать процедуру окна или описатель. 
Если вы не задаете конкретный класс сообщений или класс просматриваемых сообщений, то TDW наблюдает за всеми сообщениями, передаваемыми процедуре окна или его описателю. 
Добавление класса сообщений
Чтобы добавить класс сообщений, выберите в области класса сообщений команду локального меню Add (Добавление). TDW выводит следующее диалоговое окно: 
      Й[ю]НННSet message filterННННННННННННННННН»
      є Message Class                     OK    є
 (1)  є  ( ) All messages               ±±±±±±± є
 (2)  є  ( ) Mouse                              є
 (3)  є  ( ) Window                      Cancel є
 (4)  є  ( ) Input                      ±±±±±±± є
 (5)  є  ( ) System                             є
 (6)  є  ( ) Initialization              Help   є
 (7)  є  ( ) Clipboard                  ±±±±±±± є
 (8)  є  ( ) DDE                                є
 (9)  є  ( ) Non-client                         є
 (10) є  ( ) Other                              є
 (11) є  (.) Single message      ( ) Break      є  (12)
      є                          (.) Log        є  (13)
      є  ±±±±±±±±±±±±±±±±±±±±±±                 є
      ИНННННННННННННННННННННННННННННННННННННННННЅ
Рис. 11.3 Диалоговое окно Add Window
1 - все сообщения; 2 - "мышь"; 3 - окно; 4 - ввод; 5 - система; 6 - инициализация; 7 - буфер вырезанного изображения; 8 - DDE; 9 - не пользовательское; 10 - прочее; 11 - отдельное сообщение; 12 - прерывание; 13 - регистрация 
Диалоговое окно Set Message Filter (Задание фильтра сообщения) выводит вам подсказку как для класса, так и для действия, выполняемого при приеме сообщения. 
TDW по умолчанию регистрирует все сообщения, начинающиеся с WM_. Поскольку поступает так много сообщений, вы, вероятно, захотите ограничить их, выбрав в списке классов сообщений один из классов. Вы можете добавлять только по одному классу сообщений. Поэт
ому, если вы хотите отслеживать сообщения нескольких классов, для каждого класса сообщений нужно использовать команду Add. 
Классы сообщений описываются в следующей таблице:
                       Классы сообщений Windows     Таблица 11.1
 ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і  Класс сообщения     і  Описание                            і
 ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і All messages         і  Все сообщения, начинающиеся с WM_.  і
 і (все сообщения)      і                                      і
 і                      і                                      і
 і Mouse                і  Сообщения, генерируемые событием от і
 і ("мышь")             і  "мыши" (например, WM_LBUTTONWODN и  і
 і                      і  WM_MOUSEMOVE)                       і
 і                      і                                      і
 і Window               і  Сообщения от менеджера Windows      і
 і (окно)               і  (например, WM_PAINT и WM_CREATE)    і
 і                      і                                      і
 і Input                і  Сообщения, генерируемые по событию  і
 і (ввод)               і  от клавиатуры или при доступе       і
 і                      і  пользователя к меню System, полосе  і
 і                      і  прокрутки, или блоку размера        і
 і                      і  (например, WM_KEYDOWN и             і
 і                      і  WM_SYSCOMMAND)                      і
 і                      і                                      і
 і System               і  Сообщения, генерируемые при         і
 і (система)            і  изменениях в системе (например,     і
 і                      і  WM_FONTCHANGE и WM_SPOOLERSTATUS)   і
 і                      і                                      і
 і Initialization       і  Сообщения, генерируемые при         і
 і (инициализация)      і  создании диалового блока или окна   і
 і                      і  (например, WM_INITDIALOG и          і
 і                      і  WM_INITMENU)                        і
 і                      і                                      і
 і Clipboard            і  Сообщения, генерируемые, когда одна і
 і (буфер вырезанного   і  прикладная задача пытается получить і
 і изображения)         і  доступ к буферу вырезанного         і
 і                      і  изображения или окну другой         і
 і                      і  прикладной задачи (например,        і
 і                      і  WM_SIZECLIPBOARD и WM_DRAWCLIPBOARD)і
 і                      і                                      і
 і DDE                  і  Сообщения динамического обмена      і
 і (динамический        і  данными, генерируемые прикладными   і
 і обмен данными)       і  программами при коммуникации с      і
 і                      і  окнами другой прикладной программы  і
 і                      і  (например, WM_DDE_INITIATE и        і
 і                      і  WM_DDE_ACK)                         і
 і                      і                                      і
 і Non_client           і  Сообщения, генерируемые Windows     і
 і (не пользователь)    і  для обслуживания непользовательской і
 і                      і  области окна прикладной задачи      і
 і                      і  (например, WM_NCHITTEST и           і
 і                      і  WM_NCCREATE)                        і
 і                      і                                      і
 і Other                і  Любые сообщения, начинающиеся с     і
 і (прочие)             і  WM_, которые не попадают в другие   і
 і                      і  категории, например, другие         і
 і                      і  сообщения управления отображением   і
 і                      і  и многие интерфейсные               і
 і                      і  документирующие сообщения           і
 і                      і                                      і
 і Single Message       і  Любое отдельное сообщение,          і
 і (отдельное сообщение)і  начинающееся с WM_, которое вы      і
 і                      і  хотите зарегистрировать или         і
 і                      і  прервать программу по сообщению     і
 АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Для отслеживания отдельного сообщения выберите переключатель Single Message и введите имя сообщения или его номер. Если вы вводите имя сообщения, его нужно набирать в верхнем регистре (прописные буквы). 
Действием по умолчанию будет занесение сообщений в протокол регистрации. Другим действием, которое вы можете выполнить, является прерывание программы при получении сообщения, что эквивалентно установки точки останова по сообщению. 
Например, если вы хотите отследить сообщение WM_PAINT, и у вас есть программа, которая останавливается каждый раз, когда сообщение посылается в окно, выберите область выбора окна и сделайте следующее: 
1. Выберите правую область - область класса сообщений.
2. Выведите локальное меню и выберите команду Add (Добавление).
3. В диалоговом окне выберите в селективном переключателе Action (Действие) значение Break (Прерывание), а в селективном переключателе Message Name (Имя сообщения) - Single Message (Отдельное сообщение).
4. Введите в поле ввода Message Name (Имя сообщения) WM_PAINT, затем нажмите Enter. 
На Рис. 11.1 показано, как выглядит окно Windows Messages после того, как вы сделали данный выбор, и поступило сообщение. 
Удаление класса сообщений
Чтобы удалить класс сообщений, переместите курсор на элемент, затем либо выведите локальное меню и выберите команду Remove (Удаление), либо нажмите клавиши Del или Ctrl-Y. 
Чтобы удалить все классы, выберите в локальном меню команду Delete All (Удалить все). 
После того, как вы удалите все классы, выводится класс, используемый по умолчанию - Log all messages (Регистрация всех сообщений). С помощью команды Remove или Delete All этот класс сообщений удалить нельзя. 
Замечания по сообщениям Windows
Если вы выводите сообщения более чем для одного окна, то не регистритруйте все сообщения. Регистрируйте вместо этого для кажджого окна конкретные сообщения или конкретный класс сообщений, поскольку большое число сообщений, передаваемых между Windows и TD
W может привести к "зависанию" системы. 
При установки прерывания по классу сообщений от "мыши" нужно учитывать, что перед тем, как снова станет активной клавиатура, за сообщением mouse down (перемещение "мыши" вниз) должно следовать сообщение mouse up (перемещение "мыши" вверх). Это ограничени
е означает, что когда вы возвращаетесь в прикладную программу, вам может потребоваться несколько раз нажать кнопку "мыши", чтобы получить сообщение mouse up. Вы узнаете, что в Windows принято сообщение, когда увидите его в нижней области окна Windows Mes
sages. 
Если вы вводите имя описателя, но указываете, что это процедура, TDW будет воспринимать ваш ввод. Однако, когда вы запустите программу, TDW не будет регистрировать никаких сообщений. Если TDW не регистрирует сообщения после того, как вы установили описат
ель, чтобы увидеть, нажали ли вы кнопку Handle (Описатель), проверьте диалоговое окно Set Message Filter (Задание фильтра сообщений). 
Просмотр сообщений
Окно сообщений выводится в нижней области окна Windows Messages (Сообщения Windows). Эта область может содержать до 200 сообщений. 
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Send to log window    No і  Передача в окно регистрации
і Erase log                і  Стереть протокол
АДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Если вы хотите сохранить сообщения в файле, вам нужно открыть для окна Log (Регистрация) файл протокола (используйте команду ViewіLog File (ОбзоріФайл протокола), затем выберите в локальном меню команду Open Log File (Открытие файла протокола)). Затем пе
рейдите обратно в область сообщений и измените запись локального меню Send To Log Window (Передача в окно регистрации) в значение Yes (Да). 
Если вы хотите очистить область от всех сообщений, выберите команду локального меню Erase Log (Стереть протокол). На сообщения, записываемые в окно Log, эта команда влияния не оказывает. 
Получение содержимого памяти и списков модулей
Чтобы просмотреть содержимое глобальной или локальной динамически распределяемой области или модули программ Windows, выведите сначала с помощью команды ViewіLog (ОбзоріРегистрация) окно Log (Регистрация), затем выведите локальное меню. Последней командо
й в локальном меню окна Log является команда Display Windows Info (Вывод информации о Windows). Выбор этой команды приводит к выводу диалогового окна Windows Information (Информация о Windows), из которого вы можете выбрать тип списка, который нужно выво
дить, и где начинать список. 
      Й[ю]НННWindows InformationНННННННННННННННН»
      є Display                           OK    є
 (1)  є  (.) Global heap                ±±±±±±± є
 (2)  є  ( ) Local heap                         є
 (3)  є  ( ) Module list                 Cancel є
      є                                 ±±±±±±± є
 (4)  є  (.) Top                                є
 (5)  є  ( ) Bottom                      Help   є
 (6)  є  ( ) Handle                     ±±±±±±± є
      є                                         є
 (7)  є                          є
      ИНННННННННННННННННННННННННННННННННННННННННЅ
Рис. 11.4 Диалоговое окно Windows Information
1 - глобальная динамически распределяемая область памяти; 2 - локальная динамически распределяемая область памяти; 3 - список модулей; 4 - верх; 5 - низ; 6 - описатель; 7 - недоступно 
Если вы выберите параметр Global Heap (Глобальная динамически распределяемая область), то можете выбирать вывод с начала или конца списка, или с заданного места, указанного начальным описателем. 
Начальный описатель - это имя описателя глобальной памяти, установленного в вашей прикладной программе при вызове подпрограммы распределения памяти Windows (типа GlobalAlloc). Выбор начального описателя приводит к тому, что TDW будет выводить объект по о
писателю, а также следующие 4 объекта (которые следуют за ним в глобальной динамически распределяемой области). 
Листинг содержимого глобальной динамически распределяемой области памяти 
Глобальная динамически распределяемая область памяти - это глобальная область памяти, которая доступна с помощью Windows всем прикладным программам. Если вы распределяете ресурсы, такие как пиктограммы, битовые образы, диалоговые блоки и шрифты или распр
еделяете память с помощью функции GlobalAlloc, ваша прикладная программа использует глобальную динамически распределяемую область памяти. 
Чтобы увидеть список объектов данных в глобальной динамически распределяемой области, выберите в диалоговом окне Windows Information (Информация Windows) селективный переключатель Global Heap (Глобальная динамически распределяемая область памяти), затем 
выберите кнопку OK. Список объектов данных выведется в окне Log (Регистрация). 
Поскольку размер списка будет выроятно превышать число строк в окне Log (по умолчанию 50), вам следует записать содержимое в файл регистрации (с помощью локального меню окна Log) или увеличить число строк в окне Log (с помощью программы TDWINST). Можно з
адать до 200 строк. 
В следующей таблице показан пример - две выводимые строки для глобальной динамически распределяемой области с последующим пояснением по каждому полю. 
     Формат вывода глобальной динамически распределяемой области
                                                       Таблица 11.2
 ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і0EC5       00000040b PDB (OF1D)                                 і
 і053 (053D) 00002DC0b GDI DATA MOVEABLE LOCKED=0001 PGLOCKED=0001і
 ГДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 іПоле          і Описание                                        і
 ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 іOEC5          і Описатель или объект памяти, выраженный в виде  і
 і              і в виде шестнадцатиричного значения из 4 цифр илиі
 і              і слова FREE, что указывает на свободный блок     і
 і              і памяти.                                         і
 і              і                                                 і
 і(053D)        і Селектор памяти, указывающий на запись в таблицеі
 і              і глобальных дескрипторов. Если у него то же      і
 і              і значение, что и у описателя памяти, то селектор і
 і              і не выводится.                                   і
 і              і                                                 і
 і00000040b     і Шестнадцатиричное число, представляющее длину   і
 і00002DC0b     і сегмента в байтах.                              і
 і              і                                                 і
 іPDB           і Для кого распределяется сегмент. Обычно это     і
 іGDI           і прикладная программа или библиотечный модуль.   і
 і              і PDB - это блок описания процесса, который       і
 і              і называют также префиксом программного сегмента  і
 і              і PSP.                                            і
 і              і                                                 і
 і(0F1D)        і Описатель, указывающий на владельца PDB.        і
 і              і                                                 і
 іDATA          і Тип объекта памяти. Тип может быть следующим:   і
 і              і  DATA - сегмент данных прикладной программы или і
 і              і         DLL                                     і
 і              і  CODE - сегмент кода прикладной программы или   і
 і              і         DLL                                     і
 і              і  PRIV - системный объект или глобальные данные  і
 і              і         для прикладной программы или DLL.       і
 і              і                                                 і
 іMOVEABLE      і Атрибут распределения памяти. Объект может      і
 і              і иметь атрибуты FIXED, MOVEABLE или MOVEABLE     і
 і              і DISCARDABLE.                                    і
 і              і                                                 і
 іLOCKED=00001  і Для объекта MOVEABLE или MOVEABLE DISCARDABLE   і
 і              і это число блокировок объекта, который           і
 і              і используется с помощью функции GlobalLock или   і
 і              і LockData.                                       і
 і              і                                                 і
 іFGLOCKED=00001і Для улучшенного режима 386 число блокировок     і
 і              і страниц для объекта, который использует         і
 і              і функцию GlobalPageLock. Если страничная         і
 і              і блокировка установлена на объект памяти, то     і
 і              і Windows не может выгрузить на диск ни одну      і
 і              і из 4-килобайтовых страниц объекта.              і
 АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Листинг содержимого локальной динамически распределяемой области
Локальная динамически распределяемая область памяти - это частная область памяти для прикладной программы. Для других прикладных программ Windows (включая другие экземпляры той же программы) она недоступна. 
Программа не обязательно имеет локальную динамически распределяемую область памяти. Windows создает локальную динамически распределяемую область памяти прикладной программы с помощью функции LocalAlloc. 
Чтобы просмотреть список объектов данных в локальной динамически распределяемой области памяти, выберите селективный переключатель Local Heap (Локальная динамически распределяемая область памяти) в диалоговом окне Windows Information (Информация Windows)
, затем выберите "кнопку" OK. В окне Log (Протокол) выведется список объектов данных. 
Поскольку размер списка будет выроятно превышать число строк в окне Log (по умолчанию 50), вам следует записать содержимое в файл регистрации (с помощью локального меню окна Log) или увеличить число строк в окне Log (с помощью программы TDWINST). Можно з
адать до 200 строк. 
В следующей таблице приведена типичная строка вывода локальной динамически распределяемой области с последующим пояснением ее формата. 
     Формат вывода локальной динамически распределяемой области
                                                        Таблица 11.2
 ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і 05CD:      0024   BUSY   (10AF)                                 і
 ГДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і Поле          і Описание                                        і
 ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і OEC5          і Смещение объекта в локальном сегменте данных.   і
 і               і                                                 і
 і 0024          і Длина объекта в байтах.                         і
 і               і                                                 і
 і BUSY          і Размещение объекта памяти:                      і
 і               і  FREE - нераспределенный блок памяти;           і
 і               і  BUSY - распределенный объект.                  і
 і               і                                                 і
 і (10AF)        і Описатель локальной памяти для объекта.         і
 АДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
     Получение списка модулей
Чтобы увидеть список модулей задачи или DLL, которые загружены Windows, выберите многопозиционный переключатель Module List (Список модулей) в диалоговом окне Windows Information (Информация Windows), затем выберите "кнопку" OK. Список модулей выведется 
в окне Log (Протокол). 
В следующей таблице показан пример - три выводимые строки списка модулей с последующим пояснением по каждому полю. 
                Формат вывода списка модулей Windows    Таблица 11.2
 ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і Пример вывода списка модулей                                    і
 ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і 0985 TASK TDW      C:\TD\TDW.EXE                                і
 і 0E2D DLL  WINDEBUG C:\WIN3\WINDEBUG.DLL                         і
 і 0EFD TASK GENERIC  C:\TD\GENERIC.EXE                            і
 ГДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і Поле              і               Описание                      і
 ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і 0EFD              іЛогический номер сегмента памяти, выраженный і
 і                   і4-значным шестнадцатиричным значением.       і
 і                   і                                             і
 і TASK              іТип модуля. Модуль может быть либо задачей,  і
 і                   ілибо DLL.                                    і
 і                   і                                             і
 і GENERIC           іИмя модуля.                                  і
 і                   і                                             і
 і C:\TD\GENERIC.EXE іМаршрут к выполняемому файлу модуля.         і
 АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Отладка динамически компонуемых библиотек (DLL)
DLL представляет собой библиотеку подпрограмм и ресурсов Windows, компонуемых с вашей прикладной программой во время выполнения, а не компиляции. Такая компоновка во время выполнения позволяет нескольким прикладным программам разделять одну копию подпрог
рамм, данных или драйверов устройств, экономя тем самым память. При запуске прикладной программы, использующей DLL, в случае, если DLL еще не загружена в память, Windows загружает ее таким образом, чтобы программе стали доступны ее точки входа. 
При загрузке в TDW прикладной программы, с которой компонуются DLL, TDW определяет, какие из этих библиотек DLL (если они используются) имеют таблицы имен идентификаторов (были компилированы с параметром включения отладочной информации) и трассирует для 
вас эти библиотеки. Если во время выполнения прикладной программы TDW встречает вызов точки входа одной из этих DLL, то TDW загружает таблицу имен идентификаторов и исходный код этой библиотеки и устанавливает маркер строки модуля в начало подпрограммы D
LL, вызываемой прикладной программой. Затем DLL становится в окне Module, так же как и коды вашей прикладной программы. 
Примечание: Отладчик TDW может загрузить DLL, не имеющую таблицы имен идентификаторов, но только в окно CPU и только при отладке именно в окне CPU. 
При выходе из подпрограммы DLL TDW перезагружает таблицу имен идентификаторов и исходный код вашей программы и устанавливает маркер строки на следующий оператор после вызова точки входа DLL. 
Поскольку отладка DLL в TDW значительно автоматизирована, вам не нужно задавать, какую DLL нужно загрузить. Однако, вам может понадобиться выполнить и другие задачи, например: 
- Добавить DLL в список DLL;
- Установить точки прерывания, слежения и т.д. в DLL;
- Задать, какие DLL TDW не должен загружать;
- Отладить начальный код загрузки DLL.
Для выполнения любой из этих задач вы должны войти в окно диалога Load Modules or DLLs ("Загрузка модулей или DLL") при помощи команды ViewіModules. (Это окно диалога также появляется при нажатии клавиши F3). 
     Й[ю]ННННННННННLoad modules or DDL symbolsНННННННННННННННННН»
     є                                                          є
     є Source modules            DDLs & Programs                є
     є ±demo±±±±±±±±±±±  Load    ±SCRNFUNC.DDL*±±  Symbol load  є
     є ±±±±±±±±±±±±±±±±          ±DEMO.EXE*±±±±±±  °°°°°°°°°°°  є
     є ±±±±±±±±±±±±±±±±  Cancel  ±WINDEBUG.DDL±±±  Load symbols є
     є ±±±±±±±±±±±±±±±±          ±WREMOTE.EXE±±±±   ( )  No     є
     є ±±±±±±±±±±±±±±±±  Help    ±NWPOPUP.EXE±±±±   ()  Yes    є
     є ±±±±±±±±±±±±±±±±  °°°°°   ±PROGRAM.EXE±±±±               є
     є ±±±±±±±±±±±±±±±±          ±USER.EXE±±±±±±±  Debug startupє
     є ±±±±±±±±±±±±±±±±          ±GDI.EXE±±±±±±±±   ( )  No     є
     є ±±±±±±±±±±±±±±±±          ±KRNL386.EXE±±±±   ()  Yes    є
     є ±±±±±±±±±±±±±±±±          ±±±±±±±±±±±±±±±±               є
     є ±±±±±±±±±±±±±±±±                                         є
     є ±±±±±±±±±±±±±±±±          DDL name                       є
     є ±±±±±±±±±±±±±±±±          ±±±±±±±±±±±±±±±±  Add DDL      є
     є ±±±±±±±±±±±±±±±±          ±±±±±±±±±±±±±±±±  °°°°°°°°°°°  є
     ИННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј
Рис. 11.5 Диалоговое окно Load modules or DDLs
Load modules or DDL symbols - загрузка модулей или идентификаторов DDL; Source modules - исходные модули; DDLs & Programs - библиотеки DDL и программы; Load - загрузка; Symbol load - загрузка идентификаторов; Cancel - отмена; Help - справка; Debug startu
p - отладка кода инициализации; Add DDL - добавить DDL; DDL name - имя DDL 
Использование диалогового окна Load Modules or DLLs
Это окно диалога позволяет:
- Перейти к другому исходному модулю вашей прикладной программы;
- Выполнить операции (такие, как загрузка файла имен идентификаторов и исходного файда) с DLL и файлами .EXE. 
Переход к другому исходному модулю
Если вы отлаживаете прикладную программу, состоящую из нескольких исходных модулей, скомпонованных в один файл .EXE, и вам нужен доступ к модулю программы, отличному от текущего загруженного в окно Module, вы можете вызвать окно Load Modules or DLLs (Заг
рузка модулей или DDL) и выбрать один из модулей в левом списке, который называется Source Modules (Исходные модули). В этом списке перечислены все модули, скомпонованные в вашей прикладной программе. 
Для того, чтобы выбрать модуль, выделите его, нажмите клавишу Enter или дважды нажмите кнопку "мыши", либо выберите окно Load (Загрузка). Отладчик TDW выведет на дисплей окно Module (Модуль), и в нем будет находиться новый исходный модуль. 
Работа с DLL и программами
При отладке прикладной программы, с которой связана одна или более DLL (это верно для любых прикладных программ для Windows), и вы вызвали окно диалога Load Modules or DLLs (Загрузка модулей или DDL), вы увидите там список DLLs & Programs (DLL и программ
ы), в котором перечислены DLL и файлы .EXE. Этот список включает в себя все DLL и файлы .EXE, загруженные Windows в текущий момент, а также все библиотеки DLL, запускаемые при запуске прикладной программы. Он не включает DLL, которые ваша прикладная прог
рамма запускает вызовом LOADLIBRARY, если только они уже не загружены программой или Windows. 
Элементы в верхней части списка, помеченные справа многоточием, это файлы .EXE вашей прикладной программы и DLL с таблицами имен идентификаторов, вызываемые вашей прикладной программой. Если вы не не делали изменений, TDW автоматически загружает таблицу 
имен идентификаторов и исходный код для каждой помеченной DLL, всякий раз при вызове этой DLL из вашей программы. Кроме того, TDW автоматически загружает таблицу имен идентификаторов и исходный код любой библиотеки DLL, которую ваша программа запускает в
ызовом LOADLIBRARY, даже хотя сначала эта DLL может и не присутствовать в списке. (Она там появится после загрузки ее TDW). 
"Кнопки" справа от списка позволяют выполнять операции с выделенными вами DLL или прикладными программами. Окно текстового ввода под списком позволяет добавить в список DLL. Вы можете использовать эти средства следующим образом: 
         Управляющие элементы окна диалога DLLs & Programs  Таблица 11.5
 ЪДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
 і Кнопка                 і                 Описание                   і
 ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
 і Symbol load            і Загружает таблицу имен идентификаторов и   і
 і                        і исходные файлы для DLL или прикладной      і
 і                        і программы. Эта команда изменяет содержимое і
 і                        і окна Module (Модуль), и вы можете          і
 і                        і устанавливать точки останова, сообщения    і
 і                        і Windows, и т.д. для DLL.                   і
 і                        і                                            і
 і Load Symbols (No/Yes)  і Задает, загружать ли таблицу имен          і
 і                        і идентификаторов DLL и ее исходный код,     і
 і                        і когда прикладная программа вызывает DLL.   і
 і                        і Вы можете использовать этот параметр,      і
 і                        і чтобы предотвратить загрузку данной        і
 і                        і информации для библиотеки, которая не      і
 і                        і требует отладки. По умолчанию будет        і
 і                        і установено значение Yes (Да).              і
 і                        і                                            і
 і Debug startup (No/Yes) і Задает, нужно ли отлаживать код начальной  і
 і                        і загрузки DLL. По умолчанию устанавливается і
 і                        і No (Нет).                                  і
 і                        і                                            і
 і DLL Name               і Введите имя DLL, отсутствующей в списке    і
 і                        і DLLs & Programs (DDL и программы), чтобы   і
 і                        і добавить библиотеку в этот список.         і
 і                        і Добавление DLL в список позволит затем     і
 і                        і использовать для этой DLL одну из трех     і
 і                        і предыдущих команд. При необходимости можно і
 і                        і задать полный маршрут.                     і
 і                        і                                            і
 і Add DLL                і Добавить DLL в текущий блок текстового     і
 і                        і ввода в список DLLs & Programs.            і
 АДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Добавление DLL в список DLLs & Programs
Прежде чем вы сможете установить отладочные параметры, необходимость отлаживать начальный код загрузки DLL или загружать таблицу имен идентификаторов и исходный код DLL, эта DLL должна быть внесена в список DLL & Programs (DLL и программы). Библиотека DL
L, к которой обращается ваша программа, может и не быть в этом списке, поскольку сразу после загрузки программы TDW знает только о DLL, компонуемых с начальным кодом загрузки прикладной программы. Программа может также запустить DLL явно, при помощи кома
нды LOADLIBRARY. TDW не знает об этом до вызова LOADLIBRARY. 
Существует два различных типа кода начальной загрузки, упоминаемые в данном разделе: начальный код загрузки вашей прикладной программы и начальный код загрузки DLL. Некоторые DLL запускаются начальным кодом загрузки вашей прикладной программы. Когда ваша
 программа запускает DLL, выполняется начальный код загрузки DLL. 
Существует два типа начального кода загрузки DLL, рассматриваемые ниже. 
Если вы хотите добавить DLL в список DLLs & Programs, вызовите диалоговое окно Load Modules or DLLs (Загрузка модулей или DDL) (нажмите клавишу F3 или используйте команду ViewіModules (ОбзоріМодули)), перейдите к блоку текстового ввода DLL Name (имя DLL)
, введите имя DLL (если необходимо, введите полный маршрут), и активизируйте "кнопку" Add DLL, чтобы добавить это имя в список. 
Установка параметров отладки для DLL
Если вы хотите установить для DLL точки останова или слежения, или еще какие-либо параметры отладки, вызовите окно диалога Load Modules or DLLs (Загрузка модулей или DDL) (нажмите клавишу F3 или выберите команду ViewіModules), найдите DLL в списке DLLs &
 Programs, выделите его и затем используйте команду Symbol Load (Загрузка идентификатора), чтобы получить окно Module с этой библиотекой DLL в нем. В окне Module вы можете выполнить с DLL интересующие вас операции. 
Закончив работу с DLL, перед тем как вернуться к отладке вашей прикладной программы, вы должны загрузить для нее таблицу имен идентификаторов и исходный код. Вызовите окно диалога Load Modules or DLLs (Загрузка модулей или DDL), выберите там файл .EXE ва
шей прикладной программы и используйте "кнопку" Symbol Load. 
Управление загрузкой TDW таблиц имен идентификаторов DLL
По умолчанию TDW загружает таблицу имен идентификаторов и исходный код для каждой DLL, к которой обращается ваша прикладная программа, но только если DLL имеет совместимую таблицу имен идентификаторов. DLL имеет таблицу имен идентификаторов, совместимую 
с TDW. При компиляции с включенной информации для отладки и с помощью компилятора Турбо Паскаля для Windows DLL содержит таблицу идентификаторов, совместимую с TDW. 
Поскольку загрузка отладочной информации для DLL и затем загрузка отладочной информации для прикладной программы после того, как DLL отработает, занимает время, вам может понадобиться отменить стандартные действия для DLL, которую вы не хотите отлаживать
. Чтобы TDW не загружал таблицу имен идентификаторов для DLL, вызовите окно диалога Load Modules or DLLs (нажатием клавиши F3 или командой ViewіModules), найдите имя этой DLL в списке DLLs & Programs, выделите его и активизируйте "кнопку" Load Symbols No
. 
Отладка начального кода загрузки DLL
По умолчанию TDW не отлаживает начальный код загрузки DLL, а только загружает таблицу имен идентификаторов DLL, когда ваша прикладная программа вызывает точку входа этой DLL. Затем TDW вызывает окно Module или CPU с маркером текущей строки на начале подп
рограммы DLL, вызванной прикладной программой. 
Отладчик TDW будет отлаживать начальный код загрузки DLL, если вы явно зададите это. Вы можете использовать TDW для отладки любого из двух типов начального кода загрузки DLL. 
Какого рода начальный код загрузки вы отлаживаете
- Код инициализации, непосредственно после LibMain (по умолчанию).
- Ассемблерный код, скомпонованный с DLL, выполняющий начальную загрузку и содержит эмулированные математические пакеты для используемой DLL модели памяти (выбираемой при запуске TDW параметром командной строки -l). 
После того, как вы задали отладку начального кода загрузки одной или более DLL вашей прикладной программы, TDW загружает таблицу имен идентификаторов для каждой библиотеки DLL либо когда начальный код загрузки вашей прикладной программы запускает эту DLL
, либо когда прикладная программа явно делает вызов LOADLIBRARY. 
Загружена ли уже ваша прикладная программа?
Если вы пытаетесь загрузить прикладную программу, а уже затем задать отладку начального кода загрузки, отладчик TDW может повести себя иначе, чем вы ожидали, так как некоторые или все библиотеки DLL могут уже оказаться загруженными. Следовательно, задава
ть отладку начального кода нужно: 
- Установив отладку для DLL до загрузки вашей прикладной программы;
- Загрузив вашу прикладную программу, указав DLL для отладки начального кода загрузки, а затем перезапустив программу (Ctrl-F2 или RunіProgram Reset). 
Выполнение отладки начального кода загрузки
Учитывая все эти предварительные замечания, используйте для задания отладки начального кода загрузки для одной или более DLL и для отладки начального кода загрузки этих библиотек следующие шаги: 
1. Вызовите окно диалога Load Modules or DLL (нажмите F3 или воспользуйтесь командой ViewіModules).
2. Найдите DLL в списке DLLs & Programs и выделите ее.
3. Активизируйте "кнопку" Debug Startup Yes.
4. Повторите шаги 2 и 3, пока вы не зададите отладку начального кода загрузки для всех библиотек DLL, для которых это необходимо.
5. Если нужная вам DLL не в списке или в списке нет DLL (поскольку вы еще не загрузили прикладную программу), используйте поле текстового ввода DLL Name для ввода каждого имени DLL и добавления его в список при помощи "кнопки" Add DLL, а затем нажмите "к
нопку" Debug Startup Yes (Отладка начального кода разрешена).
6. После того, как вы установили все DLL, для которых вы хотите отлаживать начальный код загрузки, следующим шагом будет либо загрузка при помощи команды FileіLoad (ФайліЗагрузка) вашей прикладной программы (если вы еще ее не загрузили), либо перезагрузк
а программы при помощи команды RunіProgram Reset (ВыполнениеіСброс программы) (если вы загрузили ее до того, как задали отладку начального кода загрузки).
7. Когда ваша прикладная программа запускает каждую из DLL, отладчик TDW выводит либо LibMain DLL в окне Module (по умолчанию), либо начало листинга ассемблерного кода начальной загрузки библиотеки в окне CPU (так как TDW запущен с параметром -l).
8. Когда вы закончили отлаживать начальный код загрузки DLL, нажмите клавишу F9 для того, чтобы выполнить до конца начальный код загрузки и вернуться к прикладной программе. Если вы задали еще библиотеки DLL для отладки начального кода загрузки, TDW выво
дит на дисплей начальный код для этих библиотек DLL, как только программа запускает каждую из них. 
Не забудьте выполнить до конца начальный код загрузки DLL, прежде чем перезагрузить текущую прикладную программу или загрузить новую. Если вы забудете сделать это, частично выполненный начальный код DLL может привести к тому, что Windows "зависнет", и ва
м придется перезагружаться. 
Преобразование описателей памяти в адреса
Windows использует для объектов не адреса памяти, а логические номера (описатели) памяти, так как выполняет собственную организацию памяти и может изменить физическое расположение объекта в памяти. Если вам нужен фактический адрес, соответствующий логиче
скому номеру, вы можете использовать для этого встроенные имена Турбо отладчика - lh2fp (для локальных логических номеров) и gh2fp (для глобальных логических номеров) для обращения по логическому номеру к адресу памяти. 
Вы можете использовать эти имена для приведения типов в TDW, как для приведения типов указателей в Турбо Паскале обычные используются символические имена. Например, вы можете преобразовать локальный логический номер hLocalMemory двумя методами: 
- Вы можете использовать окно DataіInspect для вычисления следующего выражения: 
    (lh2fp) hLocalMemory
- Вы можете использовать команду Type Cast (Приведение типа) окна Inspector (Проверка) и ввести там lh2fp в качестве типа. 
В любом случае выражение вычисляется для первого символа блока памяти, на который указывает HLocalMemory. 
Вы можете также использовать любой из этих методов для выполнения более сложного приведения типов - например, для двухшагового приведения от логического номера к дальнему символьному указателю на дальний указатель данных в памяти, следующим образом: 
(Mystruct far *) (lh2fp)hLocalMemory


Яндекс цитирования