123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include "StdAfx.h"
- #include "DumpCollect.h"
- namespace DumpCollect
- {
- TCHAR _szDrive[_MAX_DRIVE] = { 0 };
- TCHAR _szDir[_MAX_DIR] = { 0 };
- TCHAR _szFna[_MAX_DIR] = { 0 };
- TCHAR _szExt[_MAX_DIR] = { 0 };
- TCHAR _szModulePath[MAX_PATH] = {0};
- TCHAR _szModuleFileName[MAX_PATH] = {0};
- void GetName()
- {
- static BOOL bGetName = FALSE;
- if ( bGetName )
- return;
- ::GetModuleFileName(NULL, _szModulePath, sizeof(_szModulePath) / sizeof(TCHAR));
- _stprintf_s(_szModuleFileName, _T("%s"), _szModulePath);
- _tsplitpath_s(_szModulePath, _szDrive, _szDir, _szFna, _szExt);
- _tcscpy_s(_szModulePath, _szDrive);
- _tcscat_s(_szModulePath, _szDir);
- }
- void CreateDumpFile( IN LPCTSTR lpstrDumpFilePath, IN EXCEPTION_POINTERS *pException )
- {
- // 创建Dump文件;
- HANDLE hDumpFile = CreateFile( lpstrDumpFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
- if ( (hDumpFile != NULL) && (hDumpFile != INVALID_HANDLE_VALUE) )
- {
- // Dump信息;
- MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
- ZeroMemory(&dumpInfo, sizeof(MINIDUMP_EXCEPTION_INFORMATION));
- dumpInfo.ThreadId = GetCurrentThreadId();
- dumpInfo.ExceptionPointers = pException;
- dumpInfo.ClientPointers = TRUE;
- // 写入Dump文件内容;
- MINIDUMP_CALLBACK_INFORMATION mci;
- ZeroMemory(&mci, sizeof(MINIDUMP_CALLBACK_INFORMATION));
- mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
- mci.CallbackParam = 0;
- ::MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, (pException != NULL) ? &dumpInfo : NULL, NULL, &mci );
- CloseHandle(hDumpFile);
- }
- }
- BOOL CALLBACK MiniDumpCallback( IN PVOID pParam, IN const PMINIDUMP_CALLBACK_INPUT pInput, IN PMINIDUMP_CALLBACK_OUTPUT pOutput )
- {
- if ( pInput == NULL || pOutput == NULL )
- {
- 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:
- break;
- }
- return FALSE;
- }
- BOOL IsDataSectionNeeded( IN const WCHAR* pModuleName )
- {
- if ( pModuleName == NULL || pModuleName[0] == '\0' )
- {
- return FALSE;
- }
- WCHAR szFileName[_MAX_FNAME] = L"";
- _wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);
- if ( _wcsicmp( szFileName, L"ntdll" ) == 0 )
- {
- return TRUE;
- }
- return FALSE;
- }
- LONG CALLBACK MyUnhandledExceptionFilter( IN PEXCEPTION_POINTERS pExceptionInfo )
- {
- TCHAR szDumpFile[MAX_PATH] = {0};
- _stprintf_s(szDumpFile, MAX_PATH, _T("%s%s[%s].dmp"), _szModulePath, _szFna, CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S")));
- CreateDumpFile(szDumpFile, pExceptionInfo);
- return EXCEPTION_EXECUTE_HANDLER;
- }
- // 此函数一旦成功调用,之后对SetUnhandledExceptionFilter的调用将无效;
- void DisableSetUnhandledExceptionFilter()
- {
- #if 1
- void *addr = (void*)GetProcAddress(LoadLibrary(_T("kernel32.dll")), "SetUnhandledExceptionFilter");
- if ( addr )
- {
- BYTE byCode[16] = {0};
- INT nSize = 0;
- byCode[nSize++] = 0x33;
- byCode[nSize++] = 0xC0;
- byCode[nSize++] = 0xC2;
- byCode[nSize++] = 0x04;
- byCode[nSize++] = 0x00;
- DWORD dwOldFlag, dwTempFlag;
- VirtualProtect(addr, nSize, PAGE_READWRITE, &dwOldFlag);
- WriteProcessMemory(GetCurrentProcess(), addr, byCode, nSize, NULL);
- VirtualProtect(addr, nSize, dwOldFlag, &dwTempFlag);
- }
- #else
- HMODULE hkernel32 = LoadLibrary(_T("kernel32.dll"));
- if ( hkernel32 == NULL)
- {
- return ;
- }
- void *pOrgEntry = GetProcAddress(hkernel32, "SetUnhandledExceptionFilter");
- if ( pOrgEntry == NULL )
- return;
- BYTE newJump[100];
- DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
- dwOrgEntryAddr += 5;
- void *pNewFunc = &MyUnhandledExceptionFilter;
- 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);
- #endif
- }
- void InitMinDump()
- {
- GetName();
- // 注册异常处理函数;
- SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)MyUnhandledExceptionFilter);
- // 使VS2005 自动设置SetUnhandledExceptionFilter无效;
- DisableSetUnhandledExceptionFilter();
- }
- }
|