win下dmp生成和调试
1、使用多字节字符集 2、预处理添加: _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE
#pragma once #include <windows.h> #include <stdio.h> #include <imagehlp.h> #include <stdlib.h> #pragma comment(lib, "dbghelp.lib") inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName) { if (pModuleName == 0) { return FALSE; } WCHAR szFileName[_MAX_FNAME] = L""; _wsplitpath(pModuleName, NULL, NULL, szFileName, NULL); if (wcsicmp(szFileName, L"ntdll") == 0) return TRUE; return FALSE; } inline 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; } //创建Dump文件 inline void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName) { HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, 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 = FALSE; MINIDUMP_CALLBACK_INFORMATION mci; mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback; mci.CallbackParam = 0; // MiniDumpNormal 会有线程调用堆栈的信息,MiniDumpWithDataSegs会在 MiniDumpNormal 的基础上加上全局变量 MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithDataSegs, &mdei, NULL, &mci); CloseHandle(hFile); } } LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) { return NULL; } BOOL PreventSetUnhandledExceptionFilter() { #ifdef _WIN64 return TRUE; #else HMODULE hKernel32 = LoadLibrary("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 = &MyDummySetUnhandledExceptionFilter; 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; #endif } LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException) { SYSTEMTIME stSysTime; memset(&stSysTime, 0, sizeof(SYSTEMTIME)); GetLocalTime(&stSysTime); //根据字符集,有时候可能为WCHAR TCHAR szFile[MAX_PATH] = { 0 }; wsprintf(szFile, "%0.4d-%0.2d-%0.2d-%0.2d-%0.2d-%0.2d-%0.3d.dmp", \ stSysTime.wYear, stSysTime.wMonth, stSysTime.wDay, stSysTime.wHour, \ stSysTime.wMinute, stSysTime.wSecond, stSysTime.wMilliseconds); CreateMiniDump(pException, szFile); return EXCEPTION_CONTINUE_SEARCH; } //运行异常处理 void RunCrashHandler() { SetUnhandledExceptionFilter(UnhandledExceptionFilterEx); PreventSetUnhandledExceptionFilter(); }
#include <iostream> #include "minidmp.h" int main() { RunCrashHandler(); int* pTest = NULL; *pTest = 1; }
调试