创建DUMP信息的函数实现:
static void CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName)
{
HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
{
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = pep;
mdei.ClientPointers = NULL;
MINIDUMP_CALLBACK_INFORMATION mci;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
mci.CallbackParam = 0;
::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpWithFullMemory, (pep != 0) ? &mdei : 0, NULL, &mci);
CloseHandle(hFile);
}
}
static BOOL CALLBACK MiniDumpCallback(PVOID pParam, const PMINIDUMP_CALLBACK_INPUT pInput, PMINIDUMP_CALLBACK_OUTPUT pOutput)
{
if (pInput == 0 || pOutput == 0)
return FALSE;
switch (pInput->CallbackType)
{
case ModuleCallback:
if (pOutput->ModuleWriteFlags & ModuleWriteDataSeg)
if (!IsDataSectionNeeded(pInput->Module.FullPath))
pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);
case IncludeModuleCallback:
case IncludeThreadCallback:
case ThreadCallback:
case ThreadExCallback:
return TRUE;
default:;
}
return FALSE;
}
static BOOL IsDataSectionNeeded(const WCHAR* pModuleName)
{
if (pModuleName == 0)
{
return FALSE;
}
WCHAR szFileName[_MAX_FNAME] = L"";
//_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);
_wsplitpath_s(pModuleName, NULL, 0, NULL, 0, szFileName, _MAX_FNAME, NULL, 0);
//if (wcsicmp(szFileName, L"ntdll") == 0)
if (_wcsicmp(szFileName, L"ntdll") == 0)
return TRUE;
return FALSE;
}
WIN32K结构化异常筛选器函数实现:类似 catch when 的语法效果。
int __stdcall sehCrashFilter(DWORD code, LPEXCEPTION_POINTERS lpEP)
{
time_t t = time(nullptr);
tm tm_;
localtime_s(&tm_, &t);
TCHAR szModuleName[MAX_PATH];
GetModuleFileName(NULL, szModuleName, MAX_PATH);
WCHAR szFileName[_MAX_FNAME] = L"";
_wsplitpath_s(szModuleName, NULL, 0, NULL, 0, szFileName, _MAX_FNAME, NULL, 0);
WCHAR szBuffer[MAX_PATH] = { 0 };
wsprintf(szBuffer, L"%s thread[%u]_%d-%02d-%02d_%02d-%02d-%02d.txt", szFileName, GetCurrentThreadId(), tm_.tm_year + 1900, tm_.tm_mon + 1, tm_.tm_mday, tm_.tm_hour, tm_.tm_min, tm_.tm_sec);
StackWalkerToFile sw;
if (sw.OpenFile(szBuffer))
{
sw.ShowCallstack(GetCurrentThread(), lpEP->ContextRecord);
}
wsprintf(szBuffer, L"%s thread[%u]_%d-%02d-%02d_%02d-%02d-%02d.dmp", szFileName, GetCurrentThreadId(), tm_.tm_year + 1900, tm_.tm_mon + 1, tm_.tm_mday, tm_.tm_hour, tm_.tm_min, tm_.tm_sec);
CreateMiniDump(lpEP, szBuffer);
return EXCEPTION_EXECUTE_HANDLER;
}
例子程式:
#ifdef _MSC_VER
void CommonService::seh_proccess(NetworkRouteHeader* header)
{
__try
{
c_proccess(header);
}
__except (sehCrashFilter(GetExceptionCode(), GetExceptionInformation()))
{
printf("%s seh exception\n", m_serviceName.c_str());
}
}
#endif