Ловушки EXCEPTEX MFC и Win32 структурированного исключения

Переводы статьи Переводы статьи
Код статьи: 167802 - Vizualiza?i produsele pentru care se aplic? acest articol.
Развернуть все | Свернуть все

В этой статье

Аннотация

EXCEPTEX приведен пример, демонстрирующий способы перехват исключений C++ и структурированных исключений Win32. Для C++ исключения, различные вспомогательные функции, демонстрируют, как взломать открыть наиболее часто используемые классы исключений. Для структурированных исключений Win32 предоставляется вспомогательная функция, определяющая тип исключения Win32.

Следующие файлы доступны для загрузки из Центра загрузки Майкрософт::


Exceptex.exe

Дополнительные сведения о загрузке файлов поддержки Майкрософт см. в следующей статье базы знаний Майкрософт::
119591Как загрузить файлы поддержки Microsoft из Интернета
Корпорация Microsoft проверила этот файл на наличие вирусов.. Корпорация Майкрософт использует последние версии антивирусного программного обеспечения, имеющиеся на момент публикации файла.. Файл хранится на защищенных серверах, что предотвращает его несанкционированное изменение..

Дополнительная информация

Объединение Win32 и обработку исключений C++

Обработка исключений C++ и структурированной обработки исключений Win32 использовать различный синтаксис для перехвата исключения.
    // C++ Exception Handler
    try
    {
        // Do something that may raise an exception
    }
    catch( <class name> <instance of class> )
    {
        // handle exception
    }

    // Win32 Structured Exception Handler
    __try
    {
        // Do something that may raise an exception
    }
    __except( expression )
    {
        // handle exception
    }
				
Фундаментальное различие, обработка исключений с ++, который ожидает на экземпляр типа, в то время как структурированной обработки исключений Win32 перехватывает только три ints без знака.

Можно однако, объединить как C++, так и через функции _set_se_translator() обработки исключений Win32. В результате исключения Win32, которые должны быть переданы в функцию обработчика по своему усмотрению, можно переносить данные исключения Win32 в классе, и "исключение" его как C++ исключения. Это происходит автоматически, когда произошло исключения Win32 и легко появляется в программу в списке исключений C++ (см. различия при обработке исключений в infoviewer VC 5.0). Это сделано для вас автоматически, при использовании макросов ЖУРНАЛ, связанные с Log() функции.
    // Class for containing information on a Win32 Structured Exception
    class SEH_Exception {
    private:
        SEH_Exception() {}
        unsigned int m_uSECode;
    public:
        SEH_Exception(unsigned int uSECode) : m_uSECode(uSECode) {}
        ~SEH_Exception() {}
        unsigned int getSeHNumber() { return m_uSECode; }
    };

    // Handler function that passes on Win32 Exception information in the
    // C++ class SEH_Exception
    void MappingSEHtoCPPExceptions( unsigned int uExceptionCode,
                                                  _EXCEPTION_POINTERS* )
    {
        throw SEH_Exception( uExceptionCode );
    }

    // Initialize Exception Handling
    void LogEnable( ... )
    {
        // Set Win32 Exceptions to be handled as C++ typed exceptions
        _set_se_translator(MappingSEHtoCPPExceptions);

        ...
    }
				
В этом случае LogEnable вызывается один раз, в начале выполнения программы, и возникает исключения Win32 может быть зафиксировано с помощью синтаксиса C++. EXCEPTEX пример демонстрирует это с помощью кода, учитывая выше.

Типы исключений C++

Имеется несколько категорий исключений C++, которые может быть перехвачено MFC на основе программ:

  • Экземпляры классов, производных от MFC CException
  • Экземпляры класса, инкапсулирующий Win32 исключений
  • Экземпляры собственного COM _com_error класса, который вызывается Visual C++ 5.0 поддержки доступны через директивы # Import.
Для каждого из них EXCEPTEX предлагает функцию с именем LogException, перегрузка для конкретного типа перехват исключений. В каждом случае исключение вызывает экземпляр или указатель определенного типа, обычно класс C++. Существуют over-loaded версии LogException для каждого из типов исключений C++, перечисленных выше.

Ниже приведен пример объявления для перегруженной функции LogException, который будет перехватывать указатель на класс MFC CException.
    // Crack open and log details of different types of exceptions
    extern void LogException( CException    *e,
                              LPCSTR        lpszTimeStamp,
                              LPCSTR        lpszFile,
                              int           nLine        );
				
LogException также отслеживает имя файла и строки номер где последнего использования макросов исключений в стеке вызовов (при использовании модуля поддержки ЖУРНАЛ макроса).

Все эти вспомогательные функции, открыть трещин исключение и сохраняет результаты в массив строк, обрабатываемых при необходимости. Функция для записи содержимого массива строк, этот макрос TRACE() — LogDisplay().

Упрощение try/catch блоков с макросами модуля поддержки

Засорения блоки try/catch в коде можно запутанную через некоторое время. Тем не менее это позволяет упростить блоки исключений посредством использования макросов. EXCEPTEX предоставляет три макроса, чтобы упростить этот процесс, и каждый предлагает различные функциональные возможности для ведения журнала и обработки исключений. Каждый макрос записываются также для работы Visual C++ 4.X и Visual C++ 5.0, поэтому они должны проверить версию компилятора, при использовании.

Ниже приведен простой макрос, LOGQ (quiet обработку исключений с без регистрации). Он ожидает, что значения логической переменной с именем bRetVal доступен в коде. Должно иметь значение true, таким образом, чтобы макроса можно разрешить выполнение кода, который может вызвать исключение, и он устанавливает значение ЛОЖЬ, если возникает исключение.
    #if _MSC_VER < 1100    // For version VC++ 4.2 or earlier

        #define LOGQ( f ) if( bRetVal == TRUE )                \ 
                          {                                    \ 
                             try                               \ 
                             {                                 \ 
                                 f;                            \ 
                             }                                 \ 
                             catch( CException *e )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                                 e->Delete();                  \ 
                             }                                 \ 
                             catch( SEH_Exception )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                             catch(...)                        \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                          }

    #else

        #define LOGQ( f ) if( bRetVal == TRUE )                \ 
                          {                                    \ 
                             try                               \ 
                             {                                 \ 
                                f;                             \ 
                             }                                 \ 
                             catch( CException *e )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                                e->Delete();                   \ 
                             }                                 \ 
                             catch( _com_error )               \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                              }                                \ 
                             catch( SEH_Exception )            \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                             catch(...)                        \ 
                             {                                 \ 
                                bRetVal = FALSE;               \ 
                             }                                 \ 
                          }

    #endif
				
# Ifdef _MSC_VER ограничивает определение макроса, относящиеся к Visual C++ 4.X, 5.0. Версия 5.0 включает в себя перехвата для исключения недавно введенные _com_error (созданный код, созданный с помощью директивы # Import).

Следует использовать LOGQ, как показано ниже:
    int     i = 0;
    int     j;
    BOOL    bRetVal = TRUE;

    // This code is not safe
    j = 1 / i;        // Raises Win32 Divide By Zero exception

    // This code is safe
    LOGQ( j = 1 / i; )
				
Существуют две версии ЖУРНАЛ макросов, предоставляемые EXCEPTEX. Второй макрос ЖУРНАЛ используется перегруженный LogException() помощников, описанных выше.
    #define LOGE( f ) try                               \ 
                      {                                 \ 
                          f;                            \ 
                      }                                 \ 
                      catch( CException *e )            \ 
                      {                                 \ 
                          LogException( e,              \ 
                                        __TIMESTAMP__,  \ 
                                        __FILE__,       \ 
                                        __LINE__      );\ 
                      }                                 \ 
                      ...
				
Этот макрос не дает использовать флаг bRetVal. Он будет всегда выполнения кода, инкапсулированные в макрос, перехват всех исключений, возникает и их содержимое журнала.

Окончательный ЖУРНАЛ макрос, предоставляемые EXCEPTEX LOGR, сочетает в себе LOGQ и LOGE. Проверяется ли он должен выполнить код и журнал любое исключение, возникающее.
    #define LOGR( f ) if( bRetVal == TRUE )                 \ 
                      {                                     \ 
                          try                               \ 
                          {                                 \ 
                              f;                            \ 
                          }                                 \ 
                          catch( CException *e )            \ 
                          {                                 \ 
                              LogException( e,              \ 
                                            __TIMESTAMP__,  \ 
                                            __FILE__,       \ 
                                            __LINE__      );\ 
                              bRetVal = FALSE;              \ 
                          }                                 \ 
                          ...
                        }
				

Другие полезные функции

В образце EXCEPTEX предоставляет три дополнительных функций для обработки исключений.
LogDisplay()Выводит содержимое всех зарегистрированных исключений вне через макрос TRACE.

LogDisplay (...)Выводит содержимое всех зарегистрированных исключений из экземпляру CListBox.

LogSaveToFile (...)Выводит содержимое всех исключений журнала выхода в файл.

LOG.H и LOG.CPP

LOG.H и LOG.CPP содержит весь код в EXCEPTEX для обработки исключений. Оставшаяся часть образца является демонстрация LOG.H и LOG.CPP функций и макросов. Эти файлы можно легко добавить в существующий проект и были записаны для компиляции в любом Visual C++ 4.X и 5.0 в ANSI и Юникод построений. Чтобы использовать их, добавлять # относятся к файлам, используя макрос LOGE или LOGR "log.h". Если вы хотите взломать структурированные исключения Win32, кроме того, необходимо вызвать метод LogEnable один раз в начале программы.
   // One time initialization of data
    LogEnable(false);     // false to verbose mode
				
Добавьте макрос LOG в коде, можно получить данные исключения.
   ...
   LOGE(myFunction())
   ...
				
Обратите внимание, что номер файла и строки будет последний ЖУРНАЛ макроса в стеке. Если myFunction() вызывает myFun1() и myFun2(), необходимо заключить каждый вызов функции с помощью макроса ЖУРНАЛ для выходных данных для отображения которого вызов исключения в.

Не всегда можно использовать ЖУРНАЛ макросы или даже LogException() помощников в готовом виде. Они предлагаются как для удобства, и как хорошо для демонстрации обработки исключений, полный и для записи результатов любые исключения перехватываются. Они не обеспечивают end-all быть все для обработки исключений в каждой производственной среды.

ПОИСК И УСТРАНЕНИЕ НЕПОЛАДОК

Следующий код показывает, как использовать вспомогательные макросов
    LOGQ( int i = 0; )
    LOGQ( int j = 1 / i; )    // Will this raise a divide by zero?
				
Этот код создает ошибку компилятора, как определяется только в области первый макрос LOGQ. Помните, что LOGQ при развертывании.
>
    ...
    try
    {
        int i = 0;
    }
    ...

    ...
    try
    {
        int j = 1 / i;  // error C2065: 'i' : undeclared
    }
    ...
				

/ W4 и директивы # Import

При использовании флага /W4 Visual C++ и директивы # Import, вы увидите 8 предупреждения из включаемых файлов, которые использует # import.
comutil.h(905): предупреждение C4310: приведение усекает значение константы
comutil.h(928): предупреждение C4310: приведение усекает значение константы
comutil.h(1030): предупреждение C4310: приведение усекает значение константы
comutil.h(1281): предупреждение C4310: приведение усекает значение константы
comutil.h(1307): предупреждение C4310: приведение усекает значение константы
comutil.h(1476): предупреждение C4310: приведение усекает значение константы
comdef.h(242): предупреждение Предупреждение C4244: "Вернуть": преобразование из "int" без "знака короткие", возможные потери данных
Эти сообщения об ошибке можно игнорировать и не должны влиять на код.

к антивирусному программному обеспечению.

В следующем разделе infoviewer VC ++ 5.0 представляют хорошее Введение в методы обработки исключений:
Обработка исключений: Часто задаваемые вопросы
MK:@IVT:vccore/F26/D2A/S31BE4.HTM

Различия в обработке исключений
MK:@IVT:vccore/F26/D2B/S4CC99.HTM
Со следующей статьей демонстрирует методы, которые могут быть использованы, чтобы развернуть образец EXCEPTEX для обработки исключений DAO SDK.
152695Инструкции Catch и расшифровать исключения на основе SDK DAO
Определенный источник для обработки исключений Win32 можно найти в:

«Дополнительные Windows», Джеффри Рихтер, ISBN 1 57231-548 2

Свойства

Код статьи: 167802 - Последний отзыв: 14 ноября 2010 г. - Revision: 2.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft Visual C++ 4.2 Enterprise Edition
  • Microsoft Visual C++ 5.0 Enterprise Edition
  • Microsoft Visual C++ 5.0 Professional Edition
Ключевые слова: 
kbdownload kbdatabase kbfile kbsample kbmt KB167802 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:167802
Заявление об отказе относительно содержимого статьи о продуктах, поддержка которых прекращена
Эта статья содержит сведения о продуктах, поддержка которых корпорацией Майкрософт прекращена. Поэтому она предлагается как есть и обновляться не будет.

Отправить отзыв

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com