Отладка приложений

       

Просмотр параметров в стеке


В главе 5 показано, как устанавливать точки прерывания на системных и экспортируемых функциях. Одна из главных причин для установки точек прерывания на этих функциях — необходимость просматривать параметры, которые передаются в данную функцию.

С тех пор как Visual Basic 5 позволил получать "родной" код (native code), я хотел посмотреть, как работает "родная" компиляция. Каталог Visual Basic включал файлы LINK.EXE и С2.ЕХЕ. Эти две программы являются также частью Visual C++, и было любопытно посмотреть, как их использует Visual Basic, как вообще работает компиляция. Как можно понять из названия, LINK.EXE связывает объектные файлы и производит выполняемый двоичный файл. С2.ЕХЕ довольно сложен. В системе Visual C++ файл С2.ЕХЕ — это генератор кода, который производит машинный код.

Из интегрированной среды разработки (IDE) Visual C++ я открыл VB6.EXE как программу для отладки. Поскольку были загружены символы, нужно было установить точку прерывания на {,, kernel32}_CreateProcessA@40. Запустив Visual Basic, я создал простой проект, установил свойства 'Проекта для создания "родного" кода и выбрал команду File|Make из IDE Visual Basic. Точка прерывания на _CreateProcessA@4о,обеспечивает управление отладчика при запуске или С2.ЕХЕ, или LINK.EXE.

В Windows 2000 RC2 точка прерывания на _CreateProcessA@40 останавливает отладчик на адресе 0x77E8D7E6, когда инструкция, подлежащая выполнению (PUSH EBP), устанавливает стандартный кадр стека. Поскольку точка останова находится на первой инструкции функции createProcess, вершина стека содержит параметры и адрес возврата. Затем при помощи команды View|Debug Wmdows|Memory я открыл окно Memory и ввел в поле Address строку ESP, которая является именем регистра указателя стека, чтобы просмотреть содержимое стека.

По умолчанию данные в окне Memory отображаются в байтовом формате. Поиск при этом может быть довольно утомительным. Щелчок правой кнопкой мыши в окне Memory позволяет выбрать формат: byte, short hex (2 байта или WORD) и long hex (4 байта или DWORD).


На рис. 6.4 показан стек в окне Memory отладчика в начале точки прерывания на функции CreateProcess. Первое значение — адрес возврата для инструкции OxFB6B3F6J 10 следующих — Параметры фуyrwbb CreateProcess (СМ. табл. 6.5). Параметры функции CreateProcess занимают 40 байт, а каждый параметр имеет длину 4 байта. Стек растет от старших адресов памяти к младшим, а параметры помещаются в стек справа налево, поэтому параметры появляются в окне Memory в том же порядке, как в определении функции.

Рис. 6.4. Стек в окне Memory отладчика Visual C++

Просматривать индивидуальные значения первых двух параметров можно двумя способами. Первый состоит в том, чтобы использовать окно Memory, переключая его в байтовый формат и рассматривая конкретный адрес. Второй, более легкий способ, состоит в том, чтобы буксировать (мышью) адрес, который требуется рассмотреть, в окно Watch. В окне Watch для просмотра адреса следует использовать оператор приведения типов. Например, чтобы просмотреть параметр ipAppiicationName в примере, надо поместить в окно Watch строку <char*)Oxooi2EAC4. Работает любой способ просмотра, и оба должны показать следующие значения:

0х0012ЕАС4 "c:\vb\C2.EXE"

0х0012ЕВС4 "С@ -11 "e:\temp\VB815574

-f "c:\junk\vb\Forml.frm _W 3 _Gy _G5

-GS4096 _dos _Z1

-Fo"c:\junk\vb\Forml.OBJ" _Zi _QIfdiv

-ML _basic"

Таблица 6.5. Параметры, которые VB6.EXE передает В функцию CreateProcess

Значение

Тип

Параметр

0x001 2ЕАС4

LPCTSTR

IpApplicationName

0x0012EBC4

LPTSTR

IpCommandLine

0x00000000

LPSECURITY_ATTRIBUTES

IpProcessAttributes

0x00000000

LPSECURITY_ATTRIBUTES

IpThreadAttributes

0x00000001

BOOL

blnheritHandles

0x08000000

DWORD

dwCreationFlags

0x00000000

LPVOID

IpEnvi r onment

0x00000000

LPCTSTR

IpCurrentDirectory

0x001 2EA3C

LPSTARTUPINFO

IpStartupInfo

0x001 2EC60

LPPROCESS_INFORMATION

IpProcessInformation

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



Содержание раздела