利用SEH处理Unhandle Exception

昨天同事在使用我写的上位机配置软件时出了点问题,由于同事下位机初始化参数配置不正确,传给上位机软件的数据格式不对,导致配置软件内存泄露。同事让我在上位机软件加一个异常处理,然后由用户对下位机进行恢复出厂设置。有异常处理是写程序最基本的,但是前期图省事就没加,同事说了后,我想在程序里处理下位机传过来数据的地方加个try/catch就行了,加了过后发现程序捕获不到这个异常,仍旧会弹出内存读写错误。于是开始对程序进行调试,调试到产生异常的地方,弹出来的是Unhandle Exception的错误提示,在网上搜了下,原来try/catch是捕获不到Unhandle Exception异常的,如果想捕获这个异常,需要用到SEH。

SEH的全称是Structured Exception Handling,是Windows操作系统提供的一种异常处理方式。SEH是属于操作系统的特性,不为特定语言设计,从它的名字就能看出它是一种结构化的异常处理方式。SEH包括了2个部分:终止处理__try/__finally和异常处理__try/__except。

__try/__finally可以保证无论try块内的代码执行结果如何,finally块内的代码总会被调用和执行。无论try块中的代码会不会出现异常,在程序终止的时候,finally块中的代码都会被调用和执行。所以一般情况下,finally块中的代码都是用来做一些清理工作和资源的释放。

__try/__except是用来捕捉异常的,只有当try块中的代码出现异常的时候,except块中的代码才会被调用和执行。

try/catch是由C++语言自身提供的,而SEH是由windows操作系统提供的。看到这我大致那明白了,要想处理Unhandle Exception异常,就要用__try/__finally或者__try/__except,鉴于程序实际情况,我使用了__try/__except。编译的时候,出现了如下警告和错误提示:

--------------------Configuration: Demo - Win32 Debug--------------------
Compiling...
Page2.cpp
E:\快盘\DTU_Source\Demo\Page2.cpp(418) : warning C4509: nonstandard extension used: 'AnalysisCommand' uses SEH and 'vecTime' has destructor
        E:\快盘\DTU_Source\Demo\Page2.cpp(394) : see declaration of 'vecTime'
E:\快盘\DTU_Source\Demo\Page2.cpp(438) : warning C4509: nonstandard extension used: 'AnalysisCommand' uses SEH and 'tmpStr' has destructor
        E:\快盘\DTU_Source\Demo\Page2.cpp(270) : see declaration of 'tmpStr'
E:\快盘\DTU_Source\Demo\Page2.cpp(438) : warning C4509: nonstandard extension used: 'AnalysisCommand' uses SEH and 'cmdValue' has destructor
        E:\快盘\DTU_Source\Demo\Page2.cpp(269) : see declaration of 'cmdValue'
E:\快盘\DTU_Source\Demo\Page2.cpp(438) : warning C4509: nonstandard extension used: 'AnalysisCommand' uses SEH and 'cmdName' has destructor
        E:\快盘\DTU_Source\Demo\Page2.cpp(268) : see declaration of 'cmdName'
E:\快盘\DTU_Source\Demo\Page2.cpp(438) : warning C4509: nonstandard extension used: 'AnalysisCommand' uses SEH and 'str' has destructor
        E:\快盘\DTU_Source\Demo\Page2.cpp(266) : see declaration of 'str'
E:\快盘\DTU_Source\Demo\Page2.cpp(438) : error C2712: Cannot use __try in functions that require object unwinding
执行 cl.exe 时出错.


Page2.obj - 1 error(s), 0 warning(s)

大致意思是说'AnalysisCommand'使用了SEH,对象vecTime有析构函数,其中'AnalysisCommand'是__try/__except所在的函数。在网上搜到了这篇文章http://blog.csdn.net/starlee/article/details/6636723,里面说错误的原因是try块内使用了对象,要想解决这个问题,可以把使用对象的逻辑放到一个函数里,然后在try里调用这个函数,来骗过编译器。

于是我把原本_try块里面的内容都放到一个函数里,然后再在_try块里调用这个函数。改完编译了下,还是有上面的错误。又试着改了几次终于明白了,有__try/__except的函数里面不能包含任何对象(内置基本类型除外,如int等),包括函数形参类表也不能有对象。将程序改为下面这样,编译通过。程序运行时成功捕获到Unhandle Exception,并能继续运行。

void CDemoDlg::CatchTryException()
{
	_try
	{
		DispatchCommand();
	}
	_except(EXCEPTION_EXECUTE_HANDLER)
	{
		MessageBox("传递的命令格式出错");
	}
}
void CDemoDlg::DispatchCommand()
{
	m_page1.AnalysisCommand(m_commandStr);									
	m_page2.AnalysisCommand(m_commandStr);
	m_page3.AnalysisCommand(m_commandStr);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值