程序如果发给客户在生产环境下发生了崩溃,往往很难定位问题,利用PDB + Dump可以快速的帮助我们定位问题。本文的方法在使用Qt + MSVC编译器时同样可用。
vs在生成debug版程序时会自动生成PDB文件,release版可能不会生成,在工程名点击右键——属性——链接器——调试。在生成调试信息栏选择《生成调试信息》即可让vs在生成Release版时也生成PDB文件。每次生成的PDB对应本次生成的exe文件,所以要保存好发给客户的exe对应的PDB文件。
有多种配置方法可以生成Dump文件,有的需要在客户的电脑上进行配置,使用起来不方便,我们这里利用SetUnhandledExceptionFilter在程序里生成Dump文件的方法。无需配置方便使用,创建一个win32控制台程序,输入以下代码.
#include <iostream> #include <Windows.h> //包含DBG调试模块头文件 #include <DbgHelp.h> using namespace std; //加载DBG模块 #pragma comment(lib,"DbgHelp.lib") // 创建Dump文件 void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS* pException) { HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); //Dump信息 MINIDUMP_EXCEPTION_INFORMATION dumpInfo; dumpInfo.ExceptionPointers = pException; dumpInfo.ThreadId = GetCurrentThreadId(); dumpInfo.ClientPointers = TRUE; //写入Dump文件内容 MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL); CloseHandle(hDumpFile); } //处理Unhandled Exception的回调函数 long __stdcall ApplicationCrashHandler(EXCEPTION_POINTERS* pException) { //发生未处理异常时,生成一个Test.dmp文件。 CreateDumpFile(L"Test.dmp", pException); cout << "异常已记录" << endl; system("pause"); return EXCEPTION_EXECUTE_HANDLER; } int main() { //在程序开始设置未处理异常回调。 SetUnhandledExceptionFilter(ApplicationCrashHandler); //中断程序 _asm int 3; std::cout << "Hello World!\n"; std::cin.get(); }
以上代码将在程序崩溃时,生成一个Test.dmp文件。将Test.dmp与生成程序时生成的exe和pdb文件放在同一个文件夹下,用vs打开Test.dmp,然后点击使用 仅限本机 调试,即可跳转到出错代码的位置。