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


         

это на самом деле указатель


Поле DwParams — это на самом деле указатель на параметры, когда они появляются в памяти.

В главе 6 обсуждалась передача параметров в стек. Вспомним, что параметры _stdcaii-функций передаются справа налево, и стек растет от больших адресов памяти к меньшим. Поле DwParams в структуре DDEVENTINFO указывает на последний параметр в стеке, так что структура перечисляет параметры слева направо. Чтобы облегчить преобразование dwParams, было применено немного необычное преобразование типов.

В файле заголовков DEADLOCKDETECTION.H определены директивы препроцессора typedef, которые описывают списки параметров каждой перехваченной функции. Например, если бы поле eFunc имело значение eWaitForSingieObjectEx, то для получения параметров следовало бы привести тип dwParams к LPWAITFORSINGLEOBJECTEX_PARAMS. Чтобы увидеть все эти приведения в действии, обратитесь к коду TEXTFILEDDEXT.DLL на сопровождающем компакт-диске.

Хотя обработка вывода относительно проста, сбор информации может оказаться достаточно сложным. Требовалось, чтобы DeadlockDetection подключала функции синхронизации из табл. 12.1, но я не хотел, чтобы функции подключения изменяли поведение реальных функций. Также требовалось получать параметры, возвращать значения и облегчить написание функций подключения на языке C/C++. Чтобы реализовать эти возможности, пришлось поработать с отладчиком и дизассемблером.

Первоначально я написал все функции подключения так, чтобы они выполняли только передаточные функции и напрямую вызывали реальные функции. Этот подход работал великолепно. Затем я поместил параметры и возвращаемые значения для функций в локальные переменные. Получить значение, возвращаемое из реальной функции, было довольно просто, но я понял, что нет чистого способа узнать адрес возврата с помощью С/С++-функции подключения. Нужно было разместить двойное слово (DWORD) непосредственно перед текущим указателем стека. К сожалению, к тому времени, когда я мог получать управление, пролог функции языка C/C++ уже выполнил свои таинственные действия так, что указатель стека оказывался далеко от того места, где он был нужен.


Содержание  Назад  Вперед