5

MS構造化例外から例外へのマッピングコードを変更することを検討しています。新しいC++11 error_code / error_condition/exceptionメカニズムを使用する必要があります。

私の理解では、一般的な考え方では、最初にエラーコードをstd :: error_conditionコードにマップしてみてください。それができない場合は、独自のカスタムerror_conditionコードを作成してください。

std :: errcは、POSIXエラーでうまく機能するように調整されていることがわかりました。通常のOS呼び出しとはかなり異なるエラーユニバースを持つソースからコードを取得している場合、それはうまくマッピングされません。

たとえば、MicrosoftのSEHコードを見てみましょう。これらはOSからのものであるため、理論的には、POSIX以外のすべてのものと同様にマップする必要があります。しかし、それは確かにまったくうまくマッピングされていないようです:

EXCEPTION_ACCESS_VIOLATION  = permission_denied
EXCEPTION_ARRAY_BOUNDS_EXCEEDED = argument_out_of_domain perhaps?
EXCEPTION_BREAKPOINT = ?
EXCEPTION_DATATYPE_MISALIGNMENT = ?
EXCEPTION_FLT_DENORMAL_OPERAND = ? 
EXCEPTION_FLT_DIVIDE_BY_ZERO = ?
EXCEPTION_FLT_INEXACT_RESULT = ? 
EXCEPTION_FLT_INVALID_OPERATION = ?
EXCEPTION_FLT_OVERFLOW = ?
EXCEPTION_FLT_STACK_CHECK = ?
EXCEPTION_FLT_UNDERFLOW = ?
EXCEPTION_GUARD_PAGE = ?
EXCEPTION_ILLEGAL_INSTRUCTION = ?
EXCEPTION_IN_PAGE_ERROR = ?
EXCEPTION_INT_DIVIDE_BY_ZERO = ?
EXCEPTION_INT_OVERFLOW = value_too_large perhaps, but then what do I use for _STACK_OVERFLOW?
EXCEPTION_INVALID_DISPOSITION = ?
EXCEPTION_INVALID_HANDLE = ? 
EXCEPTION_NONCONTINUABLE_EXCEPTION = ? 
EXCEPTION_PRIV_INSTRUCTION = ?
EXCEPTION_SINGLE_STEP = ?
EXCEPTION_STACK_OVERFLOW = value_too_large perhaps, but then what do I use for _INT_OVERFLOW?

では、これを攻撃する最善の方法は何でしょうか?

4

1 に答える 1

2

最初に@JamesMcNellisがコメントしたように、この例外のいくつかは非常に危険であり、これらのエラーは通常コードのエラーであるため、OSに処理させてプログラムを終了させる方がよい場合があります。しかし、それらを処理して、おそらくスタックとレジスターのダンプを含むクラッシュレポートのようなものを書きたいと思うかもしれません。

それに加えてstd::error_condition、エラーstd::error_codeでのみ機能するようには設計されていません。それらの構造は、0に等しい値が成功またはエラーを示すPOSIXすべてのケースを処理できるように設計されているため、それらを使用する完全に有効なコードを記述できますが、クラスを駆動して実装する必要がありますエラーコード(この場合はNTステータスコード)と一致するエラーコードの説明を提供する仮想関数:intstd::error_codestd::error_conditionstd::error_category

class NT_status_code_error_category : std::error_category {
public:
    const char* name() const {return "NT status code";}
    std::string message( int errCode ) const {
        switch( errCode ) {
        case EXCEPTION_ACCESS_VIOLATION: return "Access violation";
        // a couple of other error codes will be handled here
        default: return "Unknown status code";
        }
    }
    std::error_condition default_error_condition( int errCode ) const {
    return std::error_condition( errCode, *this );
}
};
inline NT_status_code_error_category const& NT_status_code_category() {
    static NT_status_code_error_category res;
    return res;
}

inline std::error_code make_NT_status_error_code( int status ) {
    return std::error_code( status, NT_status_code_category() );
}
inline std::error_condition make_NT_status_error_condition( int status ) {
    return std::error_condition( status, NT_status_code_category() );
}
于 2012-10-26T20:17:45.267 に答える