诸暨麻将添加redis
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

281 行
7.2 KiB

  1. // create_dump.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "stdafx.h"
  4. #include "create_dump.h"
  5. //// 这是导出变量的一个示例
  6. //CREATE_DUMP_API int ncreate_dump=0;
  7. //
  8. //// 这是导出函数的一个示例。
  9. //CREATE_DUMP_API int fncreate_dump(void)
  10. //{
  11. // return 42;
  12. //}
  13. //
  14. //// 这是已导出类的构造函数。
  15. //// 有关类定义的信息,请参阅 create_dump.h
  16. //Ccreate_dump::Ccreate_dump()
  17. //{
  18. // return;
  19. //}
  20. #include "stdafx.h"
  21. #include <dbghelp.h>
  22. #include "create_dump.h"
  23. #include <Tlhelp32.h>
  24. #include <shlwapi.h>
  25. #include <tchar.h>
  26. #ifndef STATUS_INVALID_CRUNTIME_PARAMETER
  27. #define STATUS_INVALID_CRUNTIME_PARAMETER ((DWORD )0xC0000417L)
  28. #endif
  29. #pragma comment(lib, "shlwapi.lib")
  30. typedef BOOL
  31. (_stdcall *tMiniDumpWriteDump)(
  32. HANDLE hProcess,
  33. DWORD ProcessId,
  34. HANDLE hFile,
  35. MINIDUMP_TYPE DumpType,
  36. PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
  37. PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
  38. PMINIDUMP_CALLBACK_INFORMATION CallbackParam
  39. );
  40. static tMiniDumpWriteDump pMiniDumpWriteDump;
  41. // Global class instance
  42. // static CExceptionReport ExceptionReport;
  43. LPTOP_LEVEL_EXCEPTION_FILTER CExceptionReport::m_previousExceptionFilter = NULL;
  44. TCHAR CExceptionReport::m_pDmpFileName[MAX_PATH] = { 0 };
  45. HANDLE CExceptionReport::m_hDumpFile = INVALID_HANDLE_VALUE;
  46. BOOL CExceptionReport::m_bFirstRun = TRUE;
  47. _invalid_parameter_handler CExceptionReport::s_fnInvalidParameterHandler = NULL;
  48. CExceptionReport::CExceptionReport()
  49. {
  50. m_bFirstRun = TRUE;
  51. m_previousExceptionFilter = SetUnhandledExceptionFilter(UnhandledExceptionFilter);
  52. s_fnInvalidParameterHandler = _set_invalid_parameter_handler(&InvalidParameterHandler);
  53. // Retrieve report/dump filenames
  54. TCHAR FullPath[MAX_PATH] = { 0 };
  55. GetModuleFileName(0, FullPath, MAX_PATH);
  56. ::PathRemoveExtension(FullPath);
  57. RSExecptionTString time = FormatCurrentTimeString();
  58. _tcscat_s(FullPath, MAX_PATH, time.c_str());
  59. _tcscpy_s(m_pDmpFileName, MAX_PATH, FullPath);
  60. _tcscat_s(m_pDmpFileName, MAX_PATH, _T(".dmp"));
  61. }
  62. CExceptionReport::~CExceptionReport()
  63. {
  64. SetUnhandledExceptionFilter(m_previousExceptionFilter);
  65. }
  66. LONG WINAPI CExceptionReport::UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
  67. {
  68. if (!m_bFirstRun)
  69. {
  70. // Don't generate exception report twice
  71. if (m_previousExceptionFilter)
  72. return m_previousExceptionFilter(pExceptionInfo);
  73. else
  74. return EXCEPTION_CONTINUE_SEARCH;
  75. }
  76. else
  77. m_bFirstRun = FALSE;
  78. HMODULE hDll = LoadLibrary(_T("dbghelp.dll"));
  79. if (!hDll)
  80. {
  81. if (m_previousExceptionFilter)
  82. return m_previousExceptionFilter(pExceptionInfo);
  83. else
  84. return EXCEPTION_CONTINUE_SEARCH;
  85. }
  86. //加载写dmp函数
  87. pMiniDumpWriteDump = (tMiniDumpWriteDump)GetProcAddress(hDll, "MiniDumpWriteDump");
  88. if (pMiniDumpWriteDump == NULL)
  89. {
  90. FreeLibrary(hDll);
  91. if (m_previousExceptionFilter)
  92. return m_previousExceptionFilter(pExceptionInfo);
  93. else
  94. return EXCEPTION_CONTINUE_SEARCH;
  95. }
  96. // Suspend all threads to freeze the current state
  97. SuspendThreads();
  98. //真正的写dmp文件
  99. m_hDumpFile = CreateFile(m_pDmpFileName, GENERIC_WRITE, FILE_SHARE_READ,
  100. 0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0);
  101. if (m_hDumpFile == INVALID_HANDLE_VALUE)
  102. {
  103. TCHAR tmp[MAX_PATH];
  104. _tcscpy_s(tmp, MAX_PATH, m_pDmpFileName);
  105. TCHAR *pos = _tcsrchr(tmp, _T('\\'));
  106. if (pos)
  107. {
  108. pos++;
  109. _stprintf_s(m_pDmpFileName, MAX_PATH, _T("c:\\%s"), pos);
  110. }
  111. else
  112. _stprintf_s(m_pDmpFileName, MAX_PATH, _T("c:\\%s"), tmp);
  113. m_hDumpFile = CreateFile(m_pDmpFileName, GENERIC_WRITE, FILE_SHARE_READ,
  114. 0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0);
  115. }
  116. int nError = 0;
  117. #ifdef TRY
  118. TRY
  119. #endif
  120. {
  121. if (m_hDumpFile != INVALID_HANDLE_VALUE)
  122. writeMiniDump(pExceptionInfo);
  123. CloseHandle(m_hDumpFile);
  124. nError = 0;
  125. }
  126. #ifdef TRY
  127. CATCH_ALL(e);
  128. {
  129. CloseHandle(m_hDumpFile);
  130. }
  131. END_CATCH_ALL
  132. #endif
  133. if (nError)//happens some errors
  134. {
  135. }
  136. else //the exception report has been saved
  137. {
  138. FreeLibrary(hDll);
  139. return EXCEPTION_CONTINUE_SEARCH;
  140. }
  141. FreeLibrary(hDll);
  142. if (m_previousExceptionFilter)
  143. return m_previousExceptionFilter(pExceptionInfo);
  144. else
  145. return EXCEPTION_CONTINUE_SEARCH;
  146. }
  147. bool CExceptionReport::writeMiniDump(PEXCEPTION_POINTERS pExceptionInfo)
  148. {
  149. // Write the minidump to the file
  150. MINIDUMP_EXCEPTION_INFORMATION eInfo;
  151. eInfo.ThreadId = GetCurrentThreadId();
  152. eInfo.ExceptionPointers = pExceptionInfo;
  153. eInfo.ClientPointers = FALSE;
  154. MINIDUMP_CALLBACK_INFORMATION cbMiniDump;
  155. cbMiniDump.CallbackRoutine = 0;
  156. cbMiniDump.CallbackParam = 0;
  157. pMiniDumpWriteDump(
  158. GetCurrentProcess(),
  159. GetCurrentProcessId(),
  160. m_hDumpFile,
  161. MiniDumpNormal,
  162. pExceptionInfo ? &eInfo : NULL,
  163. NULL,
  164. &cbMiniDump);
  165. // Close file
  166. CloseHandle(m_hDumpFile);
  167. return true;
  168. }
  169. void CExceptionReport::SuspendThreads()
  170. {
  171. // Try to get OpenThread and Thread32* function from kernel32.dll, since it's not available on Win95/98
  172. typedef HANDLE(WINAPI *tOpenThread) (DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);
  173. typedef BOOL(WINAPI *tThread32First) (HANDLE hSnapshot, LPTHREADENTRY32 lpte);
  174. typedef BOOL(WINAPI *tThread32Next) (HANDLE hSnapshot, LPTHREADENTRY32 lpte);
  175. typedef HANDLE(WINAPI *tCreateToolhelp32Snapshot) (DWORD dwFlags, DWORD th32ProcessID);
  176. HMODULE hKernel32Dll = GetModuleHandle(_T("kernel32.dll"));
  177. if (!hKernel32Dll)
  178. return;
  179. tOpenThread pOpenThread = (tOpenThread)GetProcAddress(hKernel32Dll, "OpenThread");
  180. tThread32First pThread32First = (tThread32First)GetProcAddress(hKernel32Dll, "Thread32First");
  181. tThread32Next pThread32Next = (tThread32Next)GetProcAddress(hKernel32Dll, "Thread32Next");
  182. tCreateToolhelp32Snapshot pCreateToolhelp32Snapshot = (tCreateToolhelp32Snapshot)GetProcAddress(hKernel32Dll, "CreateToolhelp32Snapshot");
  183. if (!pOpenThread ||
  184. !pThread32First ||
  185. !pThread32Next ||
  186. !pCreateToolhelp32Snapshot)
  187. {
  188. return;
  189. }
  190. HANDLE hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  191. // Get information about own process/thread
  192. DWORD ownProcessId = GetCurrentProcessId();
  193. DWORD ownThreadId = GetCurrentThreadId();
  194. // Enumerate threads
  195. THREADENTRY32 entry;
  196. entry.dwSize = sizeof(THREADENTRY32);
  197. BOOL bNext = pThread32First(hSnapshot, &entry);
  198. while (bNext)
  199. {
  200. if (entry.th32OwnerProcessID == ownProcessId &&
  201. entry.th32ThreadID != ownThreadId)
  202. {
  203. // Suspen threads of own process
  204. HANDLE hThread = pOpenThread(THREAD_SUSPEND_RESUME, FALSE, entry.th32ThreadID);
  205. if (hThread)
  206. SuspendThread(hThread);
  207. }
  208. bNext = pThread32Next(hSnapshot, &entry);
  209. }
  210. }
  211. const RSExecptionTString CExceptionReport::FormatCurrentTimeString()
  212. {
  213. SYSTEMTIME st;
  214. GetLocalTime(&st);
  215. TCHAR szDateTime[1024];
  216. memset(szDateTime, 0, sizeof(szDateTime));
  217. _stprintf_s(szDateTime, 1024, _T("%04d-%02d-%02d(%02d-%02d-%02d)"),
  218. st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
  219. return RSExecptionTString(szDateTime);
  220. }
  221. void CExceptionReport::InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
  222. {
  223. RaiseException(STATUS_INVALID_CRUNTIME_PARAMETER, 0, 0, NULL); // 抛异常, 生成dump文件
  224. }