为何 SetUnhandledExceptionFilter 捕捉不到异常?

templar616 2011-06-28 05:44:55
如下面的代码所示,明显会产生buffer overrun的异常,但为何SetUnhandledExceptionFilter 却捕捉不到,不能调用SetUnhandledExceptionFilter所设定的函数?

还请路过的大侠指点一二啊~~~~谢谢! :)




char arr123[] = "abcefghijklmn";
//构造函数
CServiceLoaderDlg::CServiceLoaderDlg() : CDialog(IDD_SERVICELOADER_DIALOG)
{
::SetUnhandledExceptionFilter(process_Service_Loader_Exception);//设置异常处理函数

AfxMessageBox("CServiceLoaderDlg::CServiceLoaderDlg111");

char b[5];
strcpy(b, arr123);//这句代码会导致buffer overrun的异常

}






LONG WINAPI CServiceLoaderDlg::process_Service_Loader_Exception(struct _EXCEPTION_POINTERS* pExceptionInfo)//异常处理函数
{
AfxMessageBox("开始 执行 CServiceLoaderDlg::process_Service_Loader_Exception");

//////////////////////////////////////////////

LONG process_result = EXCEPTION_CONTINUE_SEARCH;

//////////////////////////////////////////////

//构造dump生成目录
char szDumpFileName[_MAX_PATH] = "Service_Loader_Dump_File.dmp";

//创建文件
HANDLE hFile = CreateFile(szDumpFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);

//////////////////////////////////////////////

if(hFile != INVALID_HANDLE_VALUE)
{
//创建异常信息结构体
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;

ExInfo.ThreadId = GetCurrentThreadId();
ExInfo.ExceptionPointers = pExceptionInfo;
ExInfo.ClientPointers = NULL;

//调用MiniDumpWriteDump写信息
MiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpWithFullMemory,
&ExInfo,
NULL,
NULL);

process_result = EXCEPTION_EXECUTE_HANDLER;
}
CloseHandle(hFile);

//////////////////////////////////////////////

AfxMessageBox("结束 执行 CServiceLoaderDlg::process_Service_Loader_Exception");

return process_result;
}




...全文
2152 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
templar616 2011-07-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 coding_hello 的回复:]
加了/gs的检测之后,vs2005里面有这样的代码:

/*
* Save the global cookie and cookie complement locally - using an array
* to defeat any potential stack-packing.
*/

cookie[0] = __security_cookie;
co……
[/Quote]

我把/GS缓存安全检查改为了 否,仍然会崩,且捕捉不到异常…
野男孩 2011-06-30
  • 打赏
  • 举报
回复
加了/gs的检测之后,vs2005里面有这样的代码:

/*
* Save the global cookie and cookie complement locally - using an array
* to defeat any potential stack-packing.
*/

cookie[0] = __security_cookie;
cookie[1] = __security_cookie_complement;

#if defined (_CRTBLD) && !defined (_SYSCRT)
DebuggerWasPresent = IsDebuggerPresent();
_CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE);
#endif /* defined (_CRTBLD) && !defined (_SYSCRT) */

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Make sure any filter already in place is deleted. */
SetUnhandledExceptionFilter(NULL);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnhandledExceptionFilter((EXCEPTION_POINTERS *)&GS_ExceptionPointers);

所以,部分stack overrun的问题没办法捕获到异常吧
xiaopoy 2011-06-30
  • 打赏
  • 举报
回复
那你最好在SetUnhandledExceptionFilter上下个断点,看看它最后一次调用时是否是你的函数地址。
herman~~ 2011-06-30
  • 打赏
  • 举报
回复
没在MFC里面用过,不过在C++ CONSOLE环境下测试过是可以的
templar616 2011-06-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xiaopoy 的回复:]
嘿,你要把SetUnhandledExceptionFilter放在WinMain之后,或者你的App类初始化完成之后的过程里执行,因为mfc会设置它自己的SetUnhandledExceptionFilter,而你就发现自己的宝宝被它无耻的覆盖掉了。你可以在InitInstance或窗口的On_Create或者类似的app加载完成之后的过程中SetUnhandledExceptionFilter……
[/Quote]

我是在Init函数里设置的
templar616 2011-06-29
  • 打赏
  • 举报
回复
顶一下
luoyiaibaobao 2011-06-29
  • 打赏
  • 举报
回复
路过!!!!!!!
skyworth98 2011-06-29
  • 打赏
  • 举报
回复
这个跟编译器有关。局部变量分配在栈上,有的时候,由于某些原因(比如内存对齐等等),你实际可用的空间会比你定义的要大。你想要知道具体什么原因,就在strcpy上下个断点,然后查看b指向的内存在前后的变化。
xiaopoy 2011-06-29
  • 打赏
  • 举报
回复
嘿,你要把SetUnhandledExceptionFilter放在WinMain之后,或者你的App类初始化完成之后的过程里执行,因为mfc会设置它自己的SetUnhandledExceptionFilter,而你就发现自己的宝宝被它无耻的覆盖掉了。你可以在InitInstance或窗口的On_Create或者类似的app加载完成之后的过程中SetUnhandledExceptionFilter
老邓 2011-06-29
  • 打赏
  • 举报
回复
要确保你已经正常加载了相应的DLL。
老邓 2011-06-29
  • 打赏
  • 举报
回复
GetLastError看看。
另,可参考:
/*
** Copyright (C) QPSOFT.COM All rights reserved.
*/

#ifndef INCLUDE_MINIDUMPER_H_
#define INCLUDE_MINIDUMPER_H_

#ifdef _MSC_VER

#include <string>

#include <windows.h>
#include <tchar.h>
#pragma comment(lib, "dbghelp.lib")

#include <dbghelp.h>
#pragma comment(lib, "user32.lib")

#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

namespace qp
{

typedef std::string StringA;
typedef std::wstring StringW;

#ifdef _UNICODE
typedef StringW String;
#else
typedef StringA String;
#endif // _UNICODE

typedef BOOL (WINAPI* PFNWRITEDUMP)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION);

class MiniDumper
{
protected:
MiniDumper() { ::SetUnhandledExceptionFilter(&MiniDumper::TopLevelExceptionFilter); }
~MiniDumper() {};

private:
MiniDumper(const MiniDumper&);
const MiniDumper& operator=(const MiniDumper&);

public:
static MiniDumper* Get()
{
static MiniDumper dumper;
return &dumper;
}

void Init(const String& dumpFilePath = String(), const String& appVersion = _T("1.0.0.0"))
{
if (!dumpFilePath.empty() && ::PathIsDirectory(dumpFilePath.c_str()))
m_DumpFilePath = dumpFilePath;
else
{
TCHAR appPath[MAX_PATH];
::GetModuleFileName(NULL, appPath, MAX_PATH);
::PathRemoveFileSpec(appPath);
m_DumpFilePath = appPath;
}

m_AppVersion = appVersion;
}

String GetDumpFile() const
{
SYSTEMTIME st;
::GetLocalTime(&st);
TCHAR dt[11];
wsprintf(dt, _T("%02d%02d%02d%02d%02d"), st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

TCHAR appPath[MAX_PATH];
::GetModuleFileName(NULL, appPath, MAX_PATH);
::PathRemoveExtension(appPath);

String file(m_DumpFilePath);
file += _T("\\");
file += ::PathFindFileName(appPath);
file += _T("_") + m_AppVersion + _T("_");
file += dt;
file += _T(".dmp");
return file;
}

private:
static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS* ep)
{
LONG ret = EXCEPTION_CONTINUE_SEARCH;

TCHAR dbgHelpDLL[MAX_PATH];
::GetModuleFileName(NULL, dbgHelpDLL, MAX_PATH);

::PathRemoveFileSpec(dbgHelpDLL);
::PathAppend(dbgHelpDLL, _T("dbghelp.dll"));

HMODULE module = ::LoadLibrary(dbgHelpDLL);
if (module == NULL)
return ret;

PFNWRITEDUMP MiniDumpWriteDump = (PFNWRITEDUMP)::GetProcAddress(module, "MiniDumpWriteDump");
if (MiniDumpWriteDump != NULL)
{
String dumpFile = MiniDumper::Get()->GetDumpFile();
HANDLE file = ::CreateFile(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return ret;

_MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = ::GetCurrentThreadId();
mdei.ExceptionPointers = ep;
mdei.ClientPointers = NULL;

MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithPrivateReadWriteMemory |
MiniDumpWithDataSegs |
MiniDumpWithHandleData |
/*MiniDumpWithFullMemoryInfo |*/
MiniDumpWithThreadInfo /*|
MiniDumpWithUnloadedModules*/);

if (MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), file, mdt, &mdei, NULL, NULL))
{
::MessageBox(NULL, dumpFile.c_str(), _T("Crash Report!"), MB_TOPMOST | MB_ICONSTOP);
const String openDmp(_T("/select,") + dumpFile);
::ShellExecute(NULL, _T("open"), _T("explorer.exe"), openDmp.c_str(), NULL, SW_SHOWNORMAL);
ret = EXCEPTION_EXECUTE_HANDLER;
}

CloseHandle(file);
}

return ret;
}

private:
String m_DumpFilePath;
String m_AppVersion;
};

} // namespace qp

#endif // _MSC_VER

#endif // INCLUDE_MINIDUMPER_H_
yfk 2011-06-29
  • 打赏
  • 举报
回复
大部分异常通过SetUnhandledExceptionFilter函数能捕获,不过栈溢出、覆盖的有可能捕获不到。
buffer overflow.不适合使用异常处理,因为在引发错误之前,buffer已经出现了问题,很可能有很多不相干的东西都被破坏了.异常机制已经无法恢复这种错误带来的影响了.
此外,某些编译器也会存在一些问题,参考:
http://www.cppblog.com/woaidongmao/archive/2009/10/21/99129.html?opt=admin
templar616 2011-06-29
  • 打赏
  • 举报
回复
顶一下

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧