2011-01-21 7 views
2

私のプログラムがクラッシュしないようにするため、SEHでC++例外を有効にしました。そのため、いくつかのエラー、つまりNULLポインタのアクセスが発生した場合、私のプログラムはcatch(...)でcatchすることができます。VS2008 SEHでC++例外を有効にする

私が知りたい: 1. SEHでC++例外を有効にすると、何らかの欠点がありますか? 2. catch(...)によってキャッチされた例外の詳細をどのように知ることができますか?

答えて

1
  1. 私が知る限り、パフォーマンス上の欠点はありません。なぜなら、C++の例外はSEH経由で実装されているからです。あなたがしているのは、拡張機能がOSレベルの例外を取得できるようにすることだけです。しかし、1つの大きな欠点があり、2つに触れる。

  2. 通常、__try__exceptを使用してSEH例外を捕捉します。 more information here。これは、欠点がどこにあるのかに注意してください。このように捕捉された例外は、デストラクタを実行しません。しかし、あなたができることは、_set_se_translator関数を使ってSEH例外をC++例外に変換することです。

    bool ignore_exception(unsigned pCode) 
    { 
        const unsigned ignoreList[] = {EXCEPTION_BREAKPOINT, 
         EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO, 
         EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_OVERFLOW, EXCEPTION_FLT_UNDERFLOW, 
         EXCEPTION_INT_OVERFLOW, EXCEPTION_SINGLE_STEP}; 
    
        auto result = std::search_n(std::begin(ignoreList), std::end(ignoreList), 
            1, pCode); 
        return result != std::end(ignoreList);    
    } 
    
    std::string code_string(unsigned pCode) 
    { 
        switch (pCode) 
        { 
        case EXCEPTION_ACCESS_VIOLATION: 
         return "Access violation"; 
        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 
         return "Out of array bounds"; 
        case EXCEPTION_BREAKPOINT: 
         return "Breakpoint"; 
        case EXCEPTION_DATATYPE_MISALIGNMENT: 
         return "Misaligned data"; 
        case EXCEPTION_FLT_DENORMAL_OPERAND: 
         return "Denormalized floating-point value"; 
        case EXCEPTION_FLT_DIVIDE_BY_ZERO: 
         return "Floating-point divide-by-zero"; 
        case EXCEPTION_FLT_INEXACT_RESULT: 
         return "Inexact floating-point value"; 
        case EXCEPTION_FLT_INVALID_OPERATION: 
         return "Invalid floating-point operation"; 
        case EXCEPTION_FLT_OVERFLOW: 
         return "Floating-point overflow"; 
        case EXCEPTION_FLT_STACK_CHECK: 
         return "Floating-point stack overflow"; 
        case EXCEPTION_FLT_UNDERFLOW: 
         return "Floating-point underflow"; 
        case EXCEPTION_GUARD_PAGE: 
         return "Page-guard access"; 
        case EXCEPTION_ILLEGAL_INSTRUCTION: 
         return "Illegal instruction"; 
        case EXCEPTION_IN_PAGE_ERROR: 
         return "Invalid page access"; 
        case EXCEPTION_INT_DIVIDE_BY_ZERO: 
         return "Integer divide-by-zero"; 
        case EXCEPTION_INT_OVERFLOW: 
         return "Integer overflow"; 
        case EXCEPTION_INVALID_DISPOSITION: 
         return "Invalid exception dispatcher"; 
        case EXCEPTION_INVALID_HANDLE: 
         return "Invalid handle"; 
        case EXCEPTION_NONCONTINUABLE_EXCEPTION: 
         return "Non-continuable exception"; 
        case EXCEPTION_PRIV_INSTRUCTION: 
         return "Invalid instruction"; 
        case EXCEPTION_SINGLE_STEP: 
         return "Single instruction step"; 
        case EXCEPTION_STACK_OVERFLOW: 
         return "Stack overflow"; 
        default: 
         return "Unknown exception"; 
        } 
    } 
    
    void stack_fail_thread() 
    { 
        std::cerr << "Unhandled exception:\n" 
           << code_string(EXCEPTION_STACK_OVERFLOW) << '\n'; 
        std::cerr << "Terminating." << std::endl; 
    
        // can print a stack dump of the failed 
        // thread to see what went wrong, etc... 
    
        std::exit(EXIT_FAILURE); 
    } 
    
    void exception_translator(unsigned pCode, _EXCEPTION_POINTERS*) 
    { 
        // minimize function calls if it's a stack overflow 
        if (pCode == EXCEPTION_STACK_OVERFLOW) 
        { 
         // do some additional processing in another thread, 
         // because the stack of this thread is gone 
         boost::thread t(stack_fail_thread); 
         t.join(); // will never exit 
        } 
        else if (!ignore_exception(pCode))    
        { 
         // can add a stack dump to the exception message, 
         // since these tend to be pretty severe, etc... 
         BOOST_THROW_EXCEPTION(std::runtime_error(code_string(pCode))); 
        } 
    } 
    
    void hook_signals() 
    { 
        _set_se_translator(exception_translator); 
    } 
    

    、私はいくつかのことを取り除かが、あなたのアイデアを得る:ここで

はこれを行い、私のプロジェクトの一つから何か(用途はブーストとMSVC 2010でC++ 0xの)です。このようにすべて同じ情報を抽出することができます。

関連する問題