启用windows的程序崩溃自动dump功能

以管理员身份 运行 :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();
}

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页