* blackboy psyc209@163.com
* QQ群: 135202158
* 转载请注明作者及出处
http://blog.csdn.net/blackboyofsnp/article/details/7218488
关于SetUnhandledExceptionFilter函数:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680634(v=vs.85).aspx
据我目前的了解,此函数可以使程序进程在崩溃时调用自定义的机制来处理异常,比如将发生异常时的各种信息写成 dump文件。debug版本的程序发生意外异常时所生成的dump文件,可以交给开发人员进行调试(在编译这个debug版本的 代码及相关文件没有被修改的情况下),以确定出现bug的原因。使用Visual Studio和dump文件进行调试的方法见
http://blog.sina.com.cn/s/blog_52cbfc3f0100et8c.html
以下是使用SetUnhandledExceptionFilter函数的一个例子。注意如果需要用到MiniDumpWriteDump,静态链接的话要添加 依赖库dbghelp.lib,动态链接的话要链接dbghelp.dll。
-
#include <windows.h>
-
#include <dbghelp.h>
-
#include <tchar.h>
-
-
-
LONG
WINAPI MyExptFilter(EXCEPTION_POINTERS *pExptInfo)
-
{
-
LONG
ret = EXCEPTION_CONTINUE_SEARCH;
-
TCHAR
szExePath[MAX_PATH] = {0};
-
if
(::GetModuleFileName(NULL, szExePath, MAX_PATH) > 0)
-
{
-
int
ch = _T(
'\\'
);
-
*_tcsrchr(szExePath, ch) = _T(
'\0'
);
-
_tcscat(szExePath, _T(
"\\MyDump.dmp"
));
-
}
-
-
-
HANDLE
hFile = ::CreateFile(szExePath, GENERIC_WRITE,
-
FILE_SHARE_WRITE, NULL, CREATE_NEW,
-
FILE_ATTRIBUTE_NORMAL, NULL );
-
if
(hFile != INVALID_HANDLE_VALUE)
-
{
-
MINIDUMP_EXCEPTION_INFORMATION exptInfo;
-
exptInfo.ThreadId = ::GetCurrentThreadId();
-
exptInfo.ExceptionPointers = pExptInfo;
-
-
BOOL
bOK = ::MiniDumpWriteDump(::GetCurrentProcess(),
-
::GetCurrentProcessId(),
-
hFile, MiniDumpNormal,
-
&exptInfo, NULL, NULL);
-
if
(bOK)
-
ret = EXCEPTION_EXECUTE_HANDLER;
-
}
-
-
return
ret;
-
}
-
-
int
main(
int
argc,
char
** argv)
-
{
-
LPTOP_LEVEL_EXCEPTION_FILTER pPrevFilter = ::SetUnhandledExceptionFilter(MyExptFilter);
-
if
(pPrevFilter != NULL)
-
_tprintf(_T(
"Previous exception filter exists.\n"
));
-
else
-
_tprintf(_T(
"No Previous exception filter.\n"
));
-
-
-
*(
int
*)0 = 1234;
-
-
system(
"PAUSE"
);
-
return
0;
-
}
#include <windows.h>
#include <dbghelp.h>
#include <tchar.h>
LONG WINAPI MyExptFilter(EXCEPTION_POINTERS *pExptInfo)
LONG ret = EXCEPTION_CONTINUE_SEARCH;
TCHAR szExePath[MAX_PATH] = {0};
if(::GetModuleFileName(NULL, szExePath, MAX_PATH) > 0)
int ch = _T('\\');
*_tcsrchr(szExePath, ch) = _T('\0');
_tcscat(szExePath, _T("\\MyDump.dmp"));
// 程序崩溃时,将写入程序目录下的MyDump.dmp文件
HANDLE hFile = ::CreateFile(szExePath, GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL );
if(hFile != INVALID_HANDLE_VALUE)
MINIDUMP_EXCEPTION_INFORMATION exptInfo;
exptInfo.ThreadId = ::GetCurrentThreadId();
exptInfo.ExceptionPointers = pExptInfo;
BOOL bOK = ::MiniDumpWriteDump(::GetCurrentProcess(),
::GetCurrentProcessId(),
hFile, MiniDumpNormal,
&exptInfo, NULL, NULL);
if(bOK)
ret = EXCEPTION_EXECUTE_HANDLER;
return ret;
int main(int argc, char** argv)
LPTOP_LEVEL_EXCEPTION_FILTER pPrevFilter = ::SetUnhandledExceptionFilter(MyExptFilter);
if(pPrevFilter != NULL)
_tprintf(_T("Previous exception filter exists.\n"));
_tprintf(_T("No Previous exception filter.\n"));
//只是为了让程序崩溃
*(int*)0 = 1234;
system("PAUSE");
return 0;
很多 C/C++ 程序会设置自己的 Unhandled Exception Filter 用于捕获 Unhandled exceptions 并输出一些信息(例如,创建
mini-dump 或者输出调用栈到日志文件中)。
从 VC++2005 开始出于安全因素微软改变了 CRT 的行为。在以下情况下 CRT
开发Windows C++程序跟踪异常是比较重要的功能,一般情况都需要进行全局异常捕获,并且生成dump文件。而且C++没有运行时直接获取堆栈信息的方法,返回错误或者异常处理时无法记录到堆栈信息,如果这个时候能够生成dump,对于bug分析是非常有利的。
在做 Windows 客户端应用开发时,难免遇到程序的崩溃,当程序在 debug 崩溃时,我们可以直接定位到崩溃点,但是当程序打包成 release 发布时,难免也会遇到一些崩溃问题(当然在开发时要尽量保障程序的稳定性),一般遇到这样的崩溃,我们就需要使用 dump 文件加上符号表文件来进行调试程序,所以一般的 CI 除了将 exe 上传以外还需要将符号表信息上传。
2、在代码中生成 dump 文件
#include <Windows.h>
#include <DbgHe
最近项目中新作成了一个动态链接库,长时间运行后,偶尔会崩溃。根据log分析,被调用的动态库函数最外层catch到了这个异常,但是不能定位哪里出了问题。另外虽然上层exe是有dump文件输出处理的,但是在C++中,如果异常被捕获并处理的情况下,系统就不会生成dump文件了。如果仍希望在try-catch块中捕获异常的同时生成dump文件,就必须在catch块中手动调用生成dump文件的函数。这样可以在异常被捕获后仍然生成dump文件以供后续分析。本文详细介绍下怎么生成dump文件。
关于SetUnhandledExceptionFilter函数: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680634(v=v
//生产DUMP文件
int GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExceptionPointers, PWCHAR pwAppName)
BOOL bOwnDum...
旧调重弹-SetUnhandledExceptionFilter的使用问题kongfoo/2005.12.19. Delphi中使用SetUnhandledExceptionFilter的问题 这几天在写一个测试程序,包括使用SetUnhandledExceptionFilter来反OD调试,关于SetUnhandledExceptionFilter的反调试原理之前(一年前了哈)simonzh2
用的一个关键的API:SetUnhandledExceptionFilter
//异常处理函数
function MyInt3(CONST P:EXCEPTION_POINTERS):Integer;cdecl;
add:Pointer;
begin
OutputDebugString(PChar(inttohe
dump文件,在VC中的调试还是非常非常非常有用的,因为我们也不会经每一行代码都加上日志,当然如果你愿意,也可以每一行都加上日志;
在Windows上,添加dump文件有两种方法:
方法一:一个是在程序中添加代码;
方法二:修改注册表(参考后面的bat文件写法,在win7上用管理员程序运行);建议用这个方法,方便实用;(http://blog.csdn.net/hgy413/article/...
几乎每个游戏都或多或少地存在着缺陷,辛辛苦苦完成的游戏要是最终在玩家那里崩溃了,对开发人员来说可能是最不好的消息了。不仅如此,在游戏发布前都需要经 过大量的测试,,通常用于测试的电脑上并不会安装调试环境,因此当游戏崩溃时,往往只能得到一个错误提示。如果能够在游戏崩溃时提供更多的信息,就可以为开 发人员对此进行再现或是进一步调试带来很多方便。
当然,最理想的情况就是在每个测试人员以及每个客户的电脑上安装调试环境,每次都让游戏在 调试模式下运行,这样一旦出现错误,只需要把当时的函数调用栈、各种
MSDN文档声明当一个异常到达Unhandled Exception Filter(kernel32!UnhandledExceptionFilter)并且程序没有被调试时,Unhandled Exception Filter将会调用在kernel32!SetUnhandledExceptionFilter()API作为参数指定
一:VS2005中SetUnhandledExceptionFilter函数应用http://blog.csdn.net/happyhell/archive/2009/10/24/4723300.aspx很多软件通过设置自己的异常捕获函数,捕获未处理的异常,生成报告或者日志(例如生成mini-dump文件),达到Release版本下追踪Bug的目的。但是,到了VS2005(即VC8),Mi
SetUnhandledExceptionFilter 可以注册一个异常处理函数,当一个异常产生且我们的 try - catch(或 try - expect)没有处理处理这个异常时,异常会转交给 SetUnhandledExceptionFilter ,这是我们的应用程序处理异常的最后机会。
我们可以自己触发一个异常,然后不在 try-catch 中处理它,如果存在调试器则调试器就会接管这个异常,那么这个异常就不会走到我们的 SetUnhandledExceptionFilter 注册的异常处理