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

Когда приложение стартует под отладчиком,



Когда приложение стартует под отладчиком, Windows 2000 включает проверку специальной отладочной области динамического распределения памяти (debug heap) операционной системы. Эта область не совпадает с отладочной heap-памятью С-библиотеки времени выполнения. Код этой области создается с помощью специальной API-функции — HeapCreate. О динамической области ("куче") С-библиотеки времени выполнения речь пойдет в главе 15. Поскольку отладочные heap-области используются процессами Windows 2000 довольно широко, с их информацией приходится сталкиваться часто, вот почему так важно поподробнее ознакомиться с ними. Если вы подключаете отладчик к приложению, а не стартуете приложение под отладчиком, то проверка отладочной heap-области в операционной системе Windows 2000 активизирована не будет.

Если проверка отладочной динамической области включена, то приложение будет выполняться немного медленнее, потому что когда в приложении вызывается функция HeapFree, то приходится дополнительно проверять корректность "кучи". В листинге 4-1 показан пример программы, которая портит память. Если эта программа выполняется под отладчиком, то нетрудно заметить, что функция DebugBreak вызывается дважды (на первом же вызове функции HeapFree). Ниже показан вывод, по которому видно, что при работе с heap-областью возникли некоторые проблемы.

HEAP[Heaper.exe]: Heap block at 00441E98 modified at 00441EAA past

requested size of a

HEAP[Heaper.exe]: Invalid Address specified to

RtlFreeHeapt 440000, 441eaO)

Если эта программа выполняется вне отладчика, то она завершается без сообщений о каких-либо проблемах.

Если вы используете в Windows 2000 свои собственные2 heap-области, то для того чтобы получить более полный диагностический вывод, можно включить несколько дополнительных флажков. Для этого в Platform SDK включена небольшая утилита GFLAGS.EXE. С ее помощью можно установить несколько глобальных флажков, проверяемых операционной системой при первом запуске приложения. Установки, выполненные этой утилитой для файла HEAPER.EXE, показаны на рис. 4.1. 


 Heap - "куча", область динамически распределяемой памяти. — Пер.

Что вполне возможно, т. к. не только отладчики, но и любые приложения могут вызывать функцию HeapCreate. — Пер.

 Этот набор инструментов вы можете найти на сопровождающем CD. — Пер.

Это загрузочный модуль, частью которого является функция, показанная в листинге 4-1. — Пер.

Многие опции кнопок System Registry и Kernel Mode переключателя Destination окна Global Flags являются глобальными. Нужно проявлять особую осторожность при их установке, потому что они могут оказать решающее влияние на производительность системы. Установка переключателя Destination в положение Image File Options намного безопаснее, потому что все установки влияют только на один модуль (имя которого указано в соседнем поле Image File Name).

Рис. 4.1. Вывод программы GFLAGS.EXE

Листинг 4-1. Пример разрушения heap-области Windows 2000 

void main(void)

// Создать heap-область операционной системы. 

HANDLE hHeap = HeapCreate ( 0, 128, 0) ;

// Распределить память для блока размером в 10 байтов. 

LPVOID pMem = HeapAlloc ( hHeap, 0, 10);

// Записать 12 байт в 10-байтовый блок (переполнение heap-области).

 memset ( pMem, OxAC, 12);

// Распределить новый блок размером 20 байт. 

LPVOID pMem2 = HeapAlloc ( hHeap, 0, 20);

// Записать 1 байт во второй блок.

char * pUnder = (char *)( (DWORD)pMem2 - 1);

*pUnder = 'P';

// Освободить первый блок. Это обращение к HeapFree будет

 // инициировать точку прерывания в коде отладочной heap-области

 // операционной системы.

 HeapFree ( hHeap, 0, pMem);

// Освободить второй блок. Заметим, что этот вызов не будет

 // выдавать соообщения о неполадке

 HeapFree ( hHeap, 0, pMem2);

// Освободить фиктивный блок. Заметим, что этот вызов не будет

 // выдавать сообщения о неполадке

 HeapFree ( hHeap, О, (LPVOID)Oxl); HeapDestroy ( hHeap); 

}

Если установить те же флажки, что на рис. 4.1, и повторить выполнение HEAPER.EXE, то будет получен следующий, более многословный вывод:



PAGEHEAP: process 0x490 created debug heap 00430000

(flags 0xl, 50, 25, 0, 0) 

PAGEHEAP: process 0x490 created debug heap 00CF0000

(flags Oxl, 50, 25, 0,- 0) 

PAGEHEAP: process 0x490 created debug heap 01600000

(flags Oxl, 50, 25, 0, 0)

  PAGEHEAP: Tail fill corruption detected:

 Allocation at 0x01606FF0

 Requested size 0x0000000A 

Allocated size 0x00000010

 Corruption at Ox01606FFA 

PAGEHEAP: Attempt to reference block which is not allocated

Содержимое листинга объясняют названия флажков, установленных панелью Global Flags.

Обсуждая программу GFLAGS.EXE, я хочу указать на одну очень полезную опцию — Show Loader Snaps. Если вы установите этот флажок и выполните приложение, то увидите то, что называют снимком (snap) приложения, в котором видно, где Windows 2000 загружает DLL-файлы и как она начинает организацию импорта. Если необходимо точно видеть, что делает загрузчик Windows 2000 при загрузке приложения (особенно в том случае, когда в нем обнаружена проблема), то включение этой опции может оказаться весьма полезным мероприятием. Дополнительную информацию по снимкам загрузчика можно получить в колонке Мэта Пьетрека "Under the Hood" в сентябрьском выпуске Microsoft Systems Journal за 1999 год.



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