一 使用场景:
当可执行程序在现场跑崩溃时,线程不能调试,此时就得就要考虑让程序崩溃时产生dmp文件,然后拷回来调试,dmp里面记录出错时的记录。
二 如何产生dmp文件,
以下为示范代码(VS2013),代码开始时调用SetUnhandledExceptionFilter(&MyUnhandledFilter);,出错时就会产生dmp文件,本实例中会产生errorData.dmp
#include "stdafx.h" #include"windows.h" #include <DbgHelp.h> #include<iostream> #include <direct.h> #pragma comment(lib,"User32.lib") #pragma comment(lib, "DbgHelp.Lib") struct Object { int id; char name[32]; }; void show(Object* p) { printf("Object [%d, %s] \n", p->id, p->name); } LONG WINAPI MyUnhandledFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo) { LONG ret = EXCEPTION_EXECUTE_HANDLER; SYSTEMTIME st; CHAR szFileName[_MAX_PATH]; WCHAR szFileName1[_MAX_PATH]; ::GetLocalTime(&st); _getcwd(szFileName, _MAX_PATH); strcat(szFileName, "\\errorData.dmp"); //将char *转为WCHAR * MultiByteToWideChar(CP_ACP, 0, szFileName, strlen(szFileName) + 1, szFileName1, sizeof(szFileName1) / sizeof(szFileName1[0])); //创建dmp文件 HANDLE hFile = ::CreateFile(szFileName1, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = lpExceptionInfo; ExInfo.ClientPointers = false; // 往dmp文件中写出错时的信息 BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); ::CloseHandle(hFile); } else { std::cout << "创建文件失败!" << std::endl; } return ret; } int _tmain(int argc, _TCHAR* argv[]) { SetUnhandledExceptionFilter(&MyUnhandledFilter); Object* obj = NULL; show(obj); //<--空指针 system("pause"); return 0; }View Code
上面的示范代码如果生成可执行程序放到现场就会出错(使用空指针),将现场生成的.exe .pdb和.dmp拷回。
例如:
三:复现出错时的场景
(1)将errorData.dmp文件用VS打开
(2)点击右边的“使用仅限本机进行调试,点击完后,直接跳转到出错时的那一行。