为了扩展所有答案,这是我发现最适合 100M+ 安装的答案:
或许还应该提到std::set_terminate和std::set_unexpected 。
最重要的部分是让它一切顺利:
- 所有这些处理程序都应该调用一个在互斥体/关键部分下执行的函数,以确保如果其他线程同时发生任何其他崩溃,它们都会停止并等待,而不是造成破坏。
- SIGABRT 的信号处理程序必须将自身设置为 SIGABRT 处理程序!如果没有这个,如果您从其他线程同时发生崩溃,您处理的线程将立即退出,而不会给您任何时间来处理崩溃。
- 理想情况下,错误的实际处理应该发生在另一个进程中,或者至少在进程开始时启动的另一个线程中发生,否则您将无法处理低内存条件或堆栈溢出错误。
请参阅下面的 setExceptionHandlers 以供参考。此外,您很可能不想在调试版本或IsDebuggerPresent时连接所有处理程序。
#include <signal.h>
#include <windows.h>
#include <boost/thread/mutex.hpp>
void EnableCrashingOnCrashes();
void PreventSetUnhandledExceptionFilter();
static void exceptionHandler(EXCEPTION_POINTERS* excpInfo)
{
// your code to handle the exception. Ideally it should
// marshal the exception for processing to some other
// thread and waif for the thread to complete the job
}
static boost::mutex unhandledExceptionMx;
static LONG WINAPI unhandledException(EXCEPTION_POINTERS* excpInfo = NULL)
{
boost::mutex::scoped_lock lock(unhandledExceptionMx);
if (!excpInfo == NULL)
{
__try // Generate exception to get proper context in dump
{
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
}
__except (exceptionHandler(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
exceptionHandler(excpInfo);
}
return 0;
}
static void invalidParameter(const wchar_t* expr, const wchar_t* func,
const wchar_t* file, unsigned int line, uintptr_t reserved)
{
unhandledException();
}
static void pureVirtualCall()
{
unhandledException();
}
static void sigAbortHandler(int sig)
{
// this is required, otherwise if there is another thread
// simultaneously tries to abort process will be terminated
signal(SIGABRT, sigAbortHandler);
unhandledException();
}
static void setExceptionHandlers()
{
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(unhandledException);
_set_invalid_parameter_handler(invalidParameter);
_set_purecall_handler(pureVirtualCall);
signal(SIGABRT, sigAbortHandler);
_set_abort_behavior(0, 0);
EnableCrashingOnCrashes();
PreventSetUnhandledExceptionFilter();
}