以管理员身份 运行 :OpenDump.bat 其本质是写注册表。
运行后: 任何程序崩溃都会在C:\CrashDump 产生dmp文件(比较大,约50到200M)。
至少在Win7、Win10的电脑,Win10的平板上运行正确。
OpenDump.bat
@echo off
echo 正在启用Dump...
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDump" /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f
echo Dump已经启用
pause
@echo on
其中DumpType代表的含义是:
0 = Create a custom dump
1 = Mini dump
2 = Full dump
CloseDump.bat 关闭此功能
@echo off
echo 正在关闭Dump...
reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /f
echo Dump已经关闭
pause
@echo on
也可以在程序中设置异常处理函数
保存数据仅是拯救措施,更重要的是找到错误的根源。若能在崩溃的同一时候,程序自己主动记录下崩溃时的执行信息,将有助于修正工作。微软提供了“DbgHelp”错误调试技术。调用相关功能就可以保存程序崩溃时的信息,然后借助WinDbg软件就能分析出当时的执行状况。调用“DbgHelp”的MiniDumpWriteDump函数保存以“.dmp”为后缀的Dump文件,该文件能被WinDbg读取并分析。
不要在debug的时候测试,debug的情况下异常是由调试器接管的
windbg分析dump文件 !analyze -v
#include "CMainWindow.h"
#include <QtWidgets/QApplication>
#include <windows.h>
#include <DbgHelp.h>
typedef BOOL(WINAPI *MiniDumpWriteDump_type)
( HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
MINIDUMP_TYPE DumpType,
PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
void createMiniDump(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
HMODULE hdbghelp = ::LoadLibraryA("dbghelp");
MiniDumpWriteDump_type writeDump = NULL;
if (NULL != hdbghelp)
{
writeDump = (MiniDumpWriteDump_type)::GetProcAddress(hdbghelp, "MiniDumpWriteDump");
}
else
{
::FreeLibrary(hdbghelp);
return;
}
if (NULL == writeDump)
{
::FreeLibrary(hdbghelp);
return;
}
HANDLE handleCurrentProcess = GetCurrentProcess();
DWORD dwCurrentProcessId = GetCurrentProcessId();
HMODULE currentModule = GetModuleHandle(NULL);
HANDLE handleFile = INVALID_HANDLE_VALUE;
char exeFileName[256] = { 0 };
char dmpFileName[256] = { 0 };
if (GetModuleFileNameA(currentModule, exeFileName, sizeof(exeFileName) - 1))
{
size_t len = strlen(exeFileName);
_snprintf_s(dmpFileName, sizeof(dmpFileName), sizeof(dmpFileName) - 1, "%s.dmp", exeFileName);
if (0 != strcmp(exeFileName, dmpFileName))
{
handleFile = CreateFileA(dmpFileName,
GENERIC_ALL,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
}
}
if (INVALID_HANDLE_VALUE == handleFile)
{
::FreeLibrary(hdbghelp);
return;
}
MINIDUMP_EXCEPTION_INFORMATION mei;
mei.ExceptionPointers = ExceptionInfo;
mei.ClientPointers = TRUE;
mei.ThreadId = GetCurrentThreadId();
if (writeDump(handleCurrentProcess, dwCurrentProcessId, handleFile, MiniDumpWithFullMemory, &mei, NULL, NULL))
{
CloseHandle(handleFile);
handleFile = INVALID_HANDLE_VALUE;
}
::FreeLibrary(hdbghelp);
}
LONG WINAPI SEHHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
createMiniDump(ExceptionInfo);
ExitProcess(1);
return EXCEPTION_CONTINUE_EXECUTION;
}
int main(int argc, char *argv[])
{
LPTOP_LEVEL_EXCEPTION_FILTER preFilter = SetUnhandledExceptionFilter(SEHHandler);
QApplication a(argc, argv);
CMainWindow w;
w.show();
_asm
{
mov eax, 0xff
call eax
}
return a.exec();
}