2
我不希望我的程序崩潰,所以我啓用了C++ Exception with SEH。所以,如果有一些錯誤,即NULL指針訪問發生,我的程序可以通過catch(...)來捕獲它。VS2008使用SEH啓用C++異常
我想知道: 1. SEH啓用C++異常有什麼缺點嗎? 2.如何通過catch(...)捕獲異常細節?
我不希望我的程序崩潰,所以我啓用了C++ Exception with SEH。所以,如果有一些錯誤,即NULL指針訪問發生,我的程序可以通過catch(...)來捕獲它。VS2008使用SEH啓用C++異常
我想知道: 1. SEH啓用C++異常有什麼缺點嗎? 2.如何通過catch(...)捕獲異常細節?
據我所知,沒有性能缺陷,因爲我非常肯定C++異常是通過SEH實現的。你所做的只是讓擴展獲得操作系統級的異常。但是,有兩個主要的缺點,即觸及。
您通常使用__try
和__except
來捕捉SEH異常; more information here。注意這是缺點的地方:以這種方式捕獲的異常不會運行析構函數。但是,您可以使用函數_set_se_translator
將SEH異常轉換爲C++異常。
下面是從我的項目之一的東西做這個(使用升壓和C++ 0x中,2010年MSVC):
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);
}
我剝幾件事情了,但你的想法。您可以通過這種方式提取所有相同的信息。