Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Функция GetExceptionlnformation - часть 3


  • ExceptionAddress — адрес машинной команды, при выполнении которой про изошло исключение
  • NumberParameters — количество параметров, связанных с исключением (0-15). Это число заполненных элементов в массиве ExceptionInformation. Почти для всех исключений значение этого элемента равно 0.
  • ExceptionInformation — массив дополнительных аргументов, описывающих ис ключение. Почти для всех исключений элементы этого массива не определены.
  • Последние два элемента структуры EXCEPTION_RECORD сообщают фильтру до полнительную информацию об исключении. Сейчас такую информацию дает только один тип исключений EXCEPTION_ACCESS_VIOLATION. Все остальные дают нулевое значение в элементе NumberParameters. Проверив его, Вы узнаете, надо ли присмат ривать массив ExceptionInformation.

    При исключении EXCEPTION_ACCESS_VIOLATION эелемент ExceplionInformation[0] содержит флаг, указывающий тип операции, которая вызвала нарушение доступа. Если его значение равно 0, поток пытался читать недоступные ему данные; Т — записы вать данные по недоступному ему адресу. Элемент ExceptionInformation[l] определяет адрес недоступных данных.

    Эта структура позволяет писать фильтры исключений, сообщающие значительный объем информации о работе программы. Можно создать, например, такой фильтр:

    __try
    {

    ...

    }

    __except (ExpFltr(GetExceptionInformation()->ExceptionRecord))
    {

    ...

    }

    LONG ExpFltr(PEXCEPTION_RECORD pER)
    {

    char szBuf[300], *p;
    DWORD dwExceptionCode = pER->ExceptionCode;

    sprintf(szBuf, "Code = %x, Address = %p", dwExceptionCode, pER->ExceptionAddress);

    // находим конец строки
    p = strchr(szBuf, 0);

    // я использовал оператор switch на тот случай, если Microsoft
    // в будущем добавит информацию для других исключений

    switch (dwExceptionCode)
    {

    case EXCEPTION_ACCESS_VIOLATION:

    sprintf(p, "Attempt to %s data at address %p", pER->ExceptionInformation[0] ? "write" : "read", pER->ExceptionInformation[1]);
    break;

    default;

    break;

    }

    MessageBox(NULL, szBuf, "Exception", MB_OK | MB_ICONEXCLAMATION);

    return(EXCEPTION_CONTINUE_SEARCH); }

    Элемент ContextRecord структуры EXCEPTION_POINTERS указывает на структуру CONTEXT (см. главу 7), содержимое которой зависит от типа процессора.

    С помощью этой структуры, в основном содержащей по одному элементу для каж дого регистра процессора, можно получить дополнительную информацию о возник шем исключении. Увы, это потребует написания машинно-зависимого кода, способ ного распознавать тип процессора и использовать подходящую для пего структуру CONTEXT. При этом Вам придется включить в код набор директив #ifdef для разных типов процессоров. Структуры CONTEXT для различных процессоров, поддерживае мых Windows, определены в заголовочном файле WinNT.h,




    Начало  Назад  Вперед



    Книжный магазин