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



         

Обзор операторов утверждений для Visual C++ и Visual Basic - часть 2


Эти проблемы мучили нас во время разработки и, наконец, настал момент, когда вся команда бросила работу и принялась за исправление этих ошибок.

UI — User Interface, интерфейс пользователя. — Пер.

Подробнее оба отладочных процесса и их терминология поясняются в следующей главе. — Пер.

Результат

Меня буквально смешали с грязью, потому что оказалось, что проблема возникла из-за моей ошибки. В приложении BoundsChecker я отвечал за цикл отладки, и при этом использовалась отладочная библиотека Windows (Windows Debugging API), которая стартует один отладочный процесс (debugger) и управляет другим3 (debuggee), а также отвечает на события отладки, которые генерирует второй процесс. Будучи добросовестным программистом, я видел, что функция WaitForDebugEvent возвращала значения дескриптора некоторых уведомлений о событиях. Например, когда процесс стартовал под отладчиком, тот получал структуру, которая содержала дескриптор процесса и начальный поток для этого процесса.

Будучи довольно осторожным программистом, я знал, что если объект, дескриптор которого передан из API, больше не нужен, то следует освободить занимаемую этим объектом память, вызвав функцию cioseHandle. Поэтому всякий раз, когда отладочный API давал мне дескриптор, я закрывал этот дескриптор, как только заканчивал его использовать. Такая тактика казалась разумной.

Однако, к великому моему огорчению, я не прочитал интересное замечание в документации по отладочному API, в котором говорится, что отладочный АР! сам закрывает любые дескрипторы, которые он генерирует. Происходило же следующее: я держал некоторые дескрипторы, полученные из отладочного API, до тех пор, пока в них нуждался, однако закрывал я их после того, как отладочный API их уже закрыл.

Чтобы понять, как эта ситуация привела к проблеме, нужно знать, что когда дескриптор закрывается, операционная система помечает его как "доступный". Операционная система Windows NT 4, которую мы использовали в то время, является особенно агрессивной относительно повторного использования значений дескрипторов (Windows' 2000 демонстрирует такое же агрессивное поведение).


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