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

         

Трансляция структур EXCEPTION_POINTERS


Рассмотрев создание собственных обработчиков исключений и аварий, поговорим о структурах EXCEPTION_POINTERS, которые пересылаются некоторым функциям. Поскольку в этих структурах хранится вся интересная информация об авариях, я разработал набор функций, которые можно вызывать, чтобы перевести эту информацию в удобочитаемую форму. С помощью этих функций выполняется визуализация информации (для пользователя). Все эти функции можно найти в листинге 9-5.

Я пытался построить эти функции настолько просто, насколько это возможно. Все, что нужно с ними делать — это пересылать в них структуры EXCEPTION_POINTERS. Каждая функция возвращает указатель на строковую константу, которая содержит текст. Просматривая код, можно заметить, что каждая функция в этом наборе имеет "напарницу", имя которой заканчивается символами "VB1". Я пытался придумать способ, позволяющий использовать для VB-вариантов функций те же статические буферы, что и для С-функций. Были выбраны статические буферы, потому что функции обработки структур EXCEPTION_POINTERS будут использоваться в аварийной ситуации, а когда вызываются функции обработчика аварий, нельзя полагаться на распределенную память или использовать слишком много места в стеке. К сожалению, я не смог придумать ничего иного, кроме создания в Visual Basic своего собственного строчного буфера, который необходимо пересылать в соответствующие функции. В С-версиях, из-за того что можно возвращать буферы статических строк непосредственно, я просто хотел сделать эти функции более легкими для использования. При вызове функций аварийных обработчиков из Visual Basic предварительно объявите в программе глобальную строчную переменную, чтобы к моменту вызова память была доступна.

 То есть это вариант соответствующей функции для Visual Basic. — Пер.

Функция GetRegisterString просто возвращает строку форматированного регистра. Функция GetFauitReason немного интереснее — она возвращает полное, описание проблемы. Возвращаемая строка показывает процесс, причину исключения, модуль, который вызвал исключение, адрес исключения и, если символьная информация доступна — функцию, исходный файл и номер строки, где произошел аварийный останов:


CH_TESTS. EXE caused an EXCEPTION_ACCESS_VIOLATION in module CH_TESTS.EXE at 001B:004010FB, Baz()+0064 bytes, CHJTests.cpp, line 0060+0003 bytes

Наиболее интересные фуункции — GetFirstStackTraceString и GetNextstackTracestring. Как указано в их именах, они позволяют продвигаться по стеку. Как и в случае с API-функциями FindFirstFiie и FindNextFile, Можно сначала вызвать GetFirstStackTraceString И затем продолжить проход всего стека, вызывая GetNextstackTracestring до тех пор, пока она не возвратит FALSE. В дополнение к структуре EXCEPTION_POINTERS, эти функции получают параметр флагов режимов, который позволяет управлять количеством информации, отображаемой в результирующей строке. Следующая строка показывает вывод, когда все опции (флажки) этого параметра включены:

001В:004018АА (0x00000001 Ox008COF90 Ox008C0200 Ox77F8FE94) CH_TESTS.EXE, main()+1857 bytes, CHJTests.срр, line 0341+0007 bytes



Значения в круглых скобках — это четыре первых возможных параметра функции. В табл. 9.1 приведены символические идентификаторы флагов режимов и содержание строки вывода для каждого из них.

Таблица 9.1. Режимы функций GetFirststackTraceString И GetNextStackTraceString

Режим

Вывод

0

Только адрес стека

GSTSO_PARAMS

Четыре первых возможных параметра

GSTSO MODULE

Имя модуля

GSTSO SYMBOL

Символическое имя адреса стека

GSTSO_SRCLINE

Информация исходного файла и номера строки адреса стека

 


Рис. 9.1. Диалоговое окно программы CrashTest

Чтобы продемонстрировать эти функции в действии, я включил в сопровождающий CD два примера тестовых программ. Первая, CH_TEST, написана на C/C++, а вторая, CrashTest, — на Visual Basic. По этим двум программам можно получить довольно хорошее представление о том, как использовать все рассмотренные здесь функции. На рис. 9.1 показано диалоговое окно программы CrashTest с информацией аварийного сбоя.



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