1、新增文件CCreateDump.h
#pragma once #include "stdafx.h" #include <string> #include <fstream> using namespace std; class CCreateDump { public: CCreateDump(); ~CCreateDump(void); static CCreateDump* Instance(); static long __stdcall UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo); void DeclarDumpFile(std::string dmpFileName = ""); private: static std::string strDumpFile; static CCreateDump* __instance; };
2、CCreateDump.cpp
#include "stdafx.h" #include <Windows.h> #include "CCreateDump.h" #include <DbgHelp.h> #include <codecvt> #pragma comment(lib, "dbghelp.lib") CCreateDump* CCreateDump::__instance = NULL; std::string CCreateDump::strDumpFile = ""; CCreateDump::CCreateDump() { } CCreateDump::~CCreateDump(void) { } long CCreateDump::UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo) { std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converterX; std::wstring dumpFile = converterX.from_bytes(strDumpFile.c_str()); HANDLE hFile = CreateFile(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = ExceptionInfo; ExInfo.ClientPointers = FALSE; // write the dump BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); CloseHandle(hFile); if (!bOK) { DWORD dw = GetLastError(); //写dump文件出错处理,异常交给windows处理 return EXCEPTION_CONTINUE_SEARCH; } else { //在异常处结束 return EXCEPTION_EXECUTE_HANDLER; } } else { return EXCEPTION_CONTINUE_SEARCH; } return EXCEPTION_EXECUTE_HANDLER; } void CCreateDump::DeclarDumpFile(std::string dmpFileName) { SYSTEMTIME syt; GetLocalTime(&syt); char c[MAX_PATH]; sprintf_s(c, MAX_PATH, "%04d-%02d-%02d_%02d-%02d-%02d", syt.wYear, syt.wMonth, syt.wDay, syt.wHour, syt.wMinute, syt.wSecond); strDumpFile = std::string(c); if (!dmpFileName.empty()) { strDumpFile += dmpFileName; } strDumpFile += std::string(".dmp"); SetUnhandledExceptionFilter(UnhandleExceptionFilter); } CCreateDump* CCreateDump::Instance() { if (__instance == NULL) { __instance = new CCreateDump; } return __instance; }
3、main.cpp
#include <Windows.h> #include "CCreateDump.h" int main(void) { std::ofstream ofs("test.txt", std::ios::app); ofs << "begin!!!" << std::endl; ofs.close(); std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; CCreateDump::Instance()->DeclarDumpFile("dumpfile"); int *p = NULL; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; *p = 5; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::cout << "11111111111111111" << std::endl; std::ofstream ofs1("test.txt", std::ios::app); ofs1 << "end!!!" << std::endl; ofs1.close(); return 0; }
程序崩溃后,在本地exe的目录下会生成类似2020-09-24_14-06-12dumpfile.dmp的文件。
特别说明:当时直接在vs上进行运行时,不管是release还是debug模式,一运行后会直接崩溃,也不会进入异常捕获的函数,当时还以为是需要配置vs,或者是windows缺少某些系统库导致的。后来经大神提点后发现是vs调试器已经捕获导致的。直接点击exe文件运行后,生成了dump文件,完美实现生成dump。
vs使用dump文件调试方法:
1、将pdb文件、exe文件放到同一目录下
2、设置符号链接地址(pdb文件的路径):
3、附加源码路径:
项目解决方案-属性-调试源文件
4、点击“使用仅本机进行调试”
完成崩溃代码的定位。
注意:如果崩溃的断点注重定位到windows库的某个文件后停止了,需要下载windows库的pdb符号文件,然后再设置符号路径,将windows库的pbd文件路径加入。
参考博客: