posts - 126,  comments - 73,  trackbacks - 0

生成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 InfoYes (/DEBUG)。在Optimization设置ReferencesEliminate Unreferenced Data (/OPT:REF)。设置 Enable COMDAT FoldingRemove 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信息了

posted on 2010-10-13 16:35 我风 阅读(873) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2007年1月>
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(12)

随笔分类

随笔档案

文章档案

相册

收藏夹

C++

MyFavorite

搜索

  •  

积分与排名

  • 积分 - 323485
  • 排名 - 75

最新评论

阅读排行榜

评论排行榜