linux下 比较简单,这里不在说明,
windows下 相对复杂一点 SEH,用SetUnhandledExceptionFilter 来捕获 MiniDumpWriteDump 来写dmp文件,这种方法还不够完全,一些错误 一样无法捕获 比如 多次 delete ,可修改注册表 crash自动生成dmp 而不用代码去控制 结合代码控制 一起使用
#if _WIN32
#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
void myInvalidParameterHandler(const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
throw 1;
}
LONG CustomCrashHandledExceptionFilter(_EXCEPTION_POINTERS *ExceptionInfo)
{
CHAR strDumpFile[MAX_PATH] = { 0 };
SYSTEMTIME tm;
HANDLE hFile = NULL;
time_t rawtime;
struct tm * t;
time(&rawtime);
t = localtime(&rawtime);
sprintf(strDumpFile, "%d%s%d-%04d-%02d-%02d-%02d-%02d-%02d.dmp", sid, name.c_str(), g_Inner_id, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
hFile = CreateFileA(strDumpFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION ExInfo;
ExInfo.ThreadId = GetCurrentThreadId();
ExInfo.ExceptionPointers = ExceptionInfo;
ExInfo.ClientPointers = NULL;
BOOL bOK = MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&ExInfo,
NULL,
NULL);
CloseHandle(hFile);
}
return EXCEPTION_CONTINUE_SEARCH;
}
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI EmptySetUnhandledExceptionFilter(
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
return NULL;
}
void myPurecallHandler(void)
{
throw 1;
}
BOOL HookSetUnhandledExceptionFilter()
{
HMODULE hKernel32 = LoadLibraryA(("kernel32.dll"));
if (hKernel32 == NULL) return FALSE;
void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
if (pOrgEntry == NULL) return FALSE;
unsigned char newJump[100];
DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far
void *pNewFunc = &EmptySetUnhandledExceptionFilter;
DWORD dwNewEntryAddr = (DWORD)pNewFunc;
DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;
newJump[0] = 0xE9; // JMP absolute
memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
SIZE_T bytesWritten;
BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
return bRet;
}
class CrashHandler
{
public:
CrashHandler()
{
// SetErrorMode(SEM_FAILCRITICALERRORS);
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CustomCrashHandledExceptionFilter);
_purecall_handler old_pure_handle;
old_pure_handle = _set_purecall_handler(myPurecallHandler);
_invalid_parameter_handler oldHandler;
oldHandler = _set_invalid_parameter_handler(myInvalidParameterHandler);
HookSetUnhandledExceptionFilter();
}
};
#else
class CrashHandler
{
public:
CrashHandler()
{
assert(false);
}
};
#endif