Отображение внешних кодов ошибок в std::error_condition
Я смотрю на изменение структурированного кода отображения исключений в MS, мы должны использовать новый механизм C++ 11 error_code / error_condition / exception.
Насколько я понимаю, общая философия заключается в том, что вы должны сначала попытаться сопоставить свои коды ошибок с кодами std::error_condition, в противном случае создайте свои собственные пользовательские коды error_condition.
Проблема, которую я вижу, заключается в том, что std::errc хорошо приспособлен для работы с ошибками POSIX. Если я получаю коды из источника, который имеет довольно разные юниверсы ошибок, чем ваш типичный вызов ОС, он просто плохо отображается.
Например, давайте возьмем коды Microsoft SEH. Они исходят из ОС, поэтому теоретически они должны отображаться так же, как и все, что не в 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?
Так что бы лучше всего атаковать это?
1 ответ
Во-первых, как прокомментировал @JamesMcNellis, некоторые из этих исключений очень опасны, и может быть лучше позволить ОС обработать их и завершить работу вашей программы, поскольку эти ошибки обычно являются ошибкой в вашем коде. Но, возможно, вы захотите обработать их и написать что-то вроде отчета о сбое, возможно, с дампом стека и регистров.
Кроме того std::error_condition
а также std::error_code
не предназначен для работы только с POSIX
ошибки. Их структура разработана таким образом, что может справиться с любым int
значение, равное 0, указывает на успех, а в противном случае на ошибку, поэтому вы можете написать полностью допустимый код, который использует их с std::error_code
а также std::error_condition
но вы должны вести класс из std::error_category
и реализуйте его виртуальные функции, чтобы предоставить объяснение ваших кодов ошибок, которые соответствуют вашим кодам ошибок (в вашем случае коды состояния NT):
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() );
}