生成minidump目的是保存程序异常时的调用栈信息,便于寻找问题原因。
1, 添加下面得函数,
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>
LONG WINAPI GenerateDump(struct _EXCEPTION_POINTERS *pExceptionPointers)
{
LONG ret = EXCEPTION_EXECUTE_HANDLER;
BOOL bMiniDumpSuccessful;
TCHAR szPath[MAX_PATH];
TCHAR szFileName[MAX_PATH];
TCHAR* szAppName = TEXT(“AppName”);
TCHAR* szVersion = TEXT(“v1.0”);
DWORD dwBufferSize = MAX_PATH;
HANDLE hDumpFile;
SYSTEMTIME stLocalTime;
MINIDUMP_EXCEPTION_INFORMATION ExpParam;
GetLocalTime( &stLocalTime );
GetTempPath( dwBufferSize, szPath );
_stprintf( szFileName, TEXT(“%s%s”), szPath, szAppName );
CreateDirectory( szFileName, NULL );
_stprintf( szFileName, TEXT(“c:\\aaaa.dmp”));
hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = TRUE;
bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);
int i = GetLastError();
HRESULT hr = HRESULT_FROM_WIN32(i);
return ret;
}
2,在project setting中加入dbghelp.lib作为library的input,这是MiniDumpWriteDump需要的。在Debug Information Format设置Program Database (/Zi)。设置Generate Debug Info为Yes (/DEBUG)。在Optimization设置References为 Eliminate Unreferenced Data (/OPT:REF)。设置 Enable COMDAT Folding为 Remove Redundant COMDATs (/OPT:ICF)。后面两项设置可以大大缩小exe文件大小。
3,使用如下:
void SomeFunction()
{
int *pBadPtr = NULL;
*pBadPtr = 0;
}
void Ctest2Dlg::OnBnClickedButton1()
{
__try
{
SomeFunction();
}
__except(GenerateDump(GetExceptionInformation()))
{
}
}
4,使用windbg打开dmp文件,就可以看到出错时的call stack了。
几点要注意的:1)网上有文章介绍使用 SetUnhandledExceptionFilter设置异常过滤,保证出现异常时能调用minidump函数,但是这有些问题,这个函数会导致debugger失效,而且好像跟drwatson有些冲突,感觉用起来比较危险。在程序的关键部分加入__try – __exception,这样缩小捕捉范围,应该就足够用了。2)必须是用__try – __exception这样的形式,才能保证GetExceptionInformation()能正常使用。3)MiniDumpWithDataSegs这个参数我试着换成另外几个,好像都不好用。返回值都是0,经过解析lasterror都是E_INVALIDARG,奇怪。
update: 关于使用windbg
windbg下载地址在这里http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
下载安装最新版本即可,我没有搞清楚的一点是必须要设置windows的symbol目录,否则光有pdb是没法看到调用栈信息的。
使用windbg过程如下:安装。然后打开菜单file-> symbol file path,添加如下
srv*c:\symbol_local*http://msdl.microsoft.com/download/symbols;c:\debug
其中srv*c:\symbol_local*http://msdl.microsoft.com/download/symbols;指明从网上下载操作系统使用的symbol存放到c盘symbol_local目录,另外程序的symbol(pdb文件)可以放在c盘debug目录下。
windbg会显示一段时间busy或者retrieving..,然后就可以看到详细的dump信息了。
《 “Windows下C++编程生成minidump文件” 》 有 3 条评论
文章思路清楚明了
简单易懂
入门好帮手
哈哈
对于试用了C++构造函数,好像就无法使用__try catch这个方式。印象中网上有介绍解决方法,准备写个新的文章介绍一下,另外关于SetUnxxx,也准备介绍。
多谢文章指引.
ps:blog程序有点委琐.直接COPY你的代码,
如:TEXT(“AppName”);
其中的引号,被换成中文的了…