SetUnhandledExceptionFilter函数是Win32API的异常捕获函数,在程式异常结束前。会调用该函数注冊的回调函数,这样就能在进程终止前运行指定的代码,达到比如保存数据的功能。
当程序遇到未处理异常(主要指非指针造成)导致程序崩溃死,如果在异常发生之前调用了SetUnhandledExceptionFilter()函数,异常交给函数处理。MSDN中描述为:
Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.
因而,在程序开始处增加SetUnhandledExceptionFilter()函数,并在函数中启动软件可以将程序拉起来
#include <windows.h>
// 异常退出立马拉起软件
long __stdcall CrashCallback(_EXCEPTION_POINTERS* excp)
{
// 保存错误信息,写到文件
CCrashStack crashStack(excp);
QString sCrashInfo = crashStack.GetExceptionInfo();
QString sFileName = "testcrash.log";
QFile file(sFileName);
if (file.open(QIODevice::WriteOnly|QIODevice::Truncate))
{
file.write(sCrashInfo.toUtf8());
file.close();
}
// 将软件再次启动
QProcess::startDetached(qApp->applicationFilePath(), QStringList()); // 异常退出立马将软件起来
return EXCEPTION_EXECUTE_HANDLER;
}
其中保存错误信息的类如下:
// .h
#ifndef CCRASHSTACK_H
#define CCRASHSTACK_H
#include <windows.h>
#include <QString>
class CCrashStack
{
public:
CCrashStack(PEXCEPTION_POINTERS pException);
QString GetExceptionInfo();
private:
QString GetModuleByRetAddr(PBYTE Ret_Addr, PBYTE & Module_Addr);
QString GetCallStack(PEXCEPTION_POINTERS pException);
QString GetVersionStr();
private:
PEXCEPTION_POINTERS m_pException;
};
#endif // CCRASHSTACK_H
#include "ccrashstack.h"
#include <tlhelp32.h>