在写DAServer的过程中,一直在重视报文逻辑处理,却没有认认真真地去思考异常处理的问题。曾经我发现我在所有的报文处理函数中均没有考虑报文长度的问题,让我内心不由地捏了一把冷汗。我在新增的故障录波及故障报告的目录报文中引入了报文长度检查,但是其他的类型报文我还是没有克服懒惰情绪,报文类型实在是太多了……

  我想,既然没有检查报文长度,那就把C++可能的异常Catch住就行了,等出了问题再处理吧。我在带领别人编程的过程中一直都在强调:无论如何也不能保证自己不出错,但是一定要保证把系统所有可能出错的地方Catch住,保证系统即使出现问题也不能影响其他功能使用。

  不知道怎么回事,我研究C++异常处理这个重要问题的时候,却没有深入研究,以至于得到一个错误的结论是:C++只能catch显式throw出来的异常。虽然我的直觉上是表示怀疑的,但是我怎么就没有去深入研究一下呢?比如我在VS2008上新建一个默认的C++ Console工程,测试如下代码:

#include <iostream>
using namespace std; int main(int argc, char **argv)
{
try
{
throw ;
}
catch(...)
{
cout << "exception!" << endl;
} system("pause");
return ;
}

  这个一点问题都没有,显式throw一个异常,然后catch(...)来捕获所有类型的异常。但是如果测试这样的代码呢:

#include <iostream>
using namespace std; int main(int argc, char **argv)
{
try
{
int* p = (int*)0x12345678;
*p = ;
}
catch(...)
{
cout << "exception!" << endl;
} system("pause");
return ;
}

  这时将会弹出如下对话框:

  这种错误正是我希望能够捕获的,在内存访问越界、非法操作等情况下都会出现,而且我的DAServer出现异常90%都是这个错误。怎么办?今天仔细搜索了一下,我才找到问题的处理办法:

  在“启用C++异常”选项中选择“是,但有SEH异常(/EHa)”即可。

  什么是SEH异常呢?请参见文章《深入解析结构化异常处理(SEH)》。简要来说是这样的:

"""

概念:
C++异常”就是 try{}catch(...){}
SEH异常”就是 __try{} __except(-1/0/1){}
(关于这两种异常,如有不了解的地方,网上有很多资料可以参考)

目前微软所有的VC编译器(从VC6到VC2010),都默认是打开对C++异常的编译支持的(位于项目选项中的“代码生成”->启用C++异常:/EHsc,VC6是Enable Exception handling)

(以下需要仔细阅读)
  在VC6中,对EXE工程是同时默认开启“C++异常可以捕获SEH异常”。在此条件下,用“C++异常”也可以捕获向非法地址的读写等基本的Windows异常。
  如:try{ int *a=0; *a=100; }catch(...){printf("excption!");},执行到*a=100时,会跳转到catch块,并执行printf。
  但是,VC6建立的DLL或其他非EXE工程,如果是Release模式,并且编译时,启用了代码自动优化,那么结果就变成了只启用了“C++异常”,即“C++异常无法捕获SEH异常”。这样的一个后果是,在DLL中,即使像这样用try{ int *a=0; *a=100; }catch(...){printf("excption!");}保护代码,当代码执行到*a=100非法地址赋值语句时,catch(...)却什么都捕获不到,会直接造成程序崩溃。
  除非明确使用“SEH异常”__try...__except(1)..,才能捕获到这种Windows异常。
相应的解决办法:
  对于从VC7开始以及以后的VC++,在“代码生成”->“启用C++异常”处,均有第三个选项:“有效,但有SEH异常(/EHa)”,这样就是可以让程序“使用C++异常也能够捕获到SEH异常”。
  这样无论是在EXE还是DLL中,try{}catch(...){}同样可以捕获Windows异常。

  对于VC6的非EXE工程,有以下两个方法,来用try..catch..捕获Windows的SEH异常:
1、通过关闭编译时的优化(禁用或者只使用Default级别,个人感觉是因为VC6的编译器不是非常完善)。
2、通过在当前工程的编译选项中,手工加上 /EHa 参数。这个编译选项是没有界面可以去设置的,只能手工添加。
  这两个方法选择任何一个都可以。建议使用第二个方法。另外要注意“C++异常”与“SEH异常”无法同时在同一个函数中混用。
"""

在VS2008环境下的C++异常处理的更多相关文章

  1. 在VS2008环境下编写C语言DLL,并在C++和C#项目下调用 (转载)

    1.编写DLL a)文件--打开--新建项目--Win32,右侧Win32项目,填写好项目名称,点击"下一步", 应用程序类型选择:"DLL(D)",附加选项: ...

  2. Oracle 11g RAC环境下Private IP修改方法及异常处理

    Oracle 11g RAC环境下Private IP修改方法及异常处理 Oracle 11g RAC环境下Private IP修改方法及异常处理 一. 修改方法 1. 确认所有节点CRS服务以启动 ...

  3. 编译mapnik(win7 环境下vs2008编译mapnik 0.7.1 成功)

    编译mapnik(win7 环境下vs2008编译mapnik 0.7.1 成功) ------by  wangsh 2012.02.22 Mapnik 是一个开源的 Python/C++ 地图渲染引 ...

  4. Windows环境下32位汇编语言程序设计(典藏版)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...

  5. [原]我在Windows环境下的首个Libevent测试实例

    libevent对Windows环境也有很好的支持,不过初次学习和编译libevent简单实例,总是有一些陌生感的,只有成功编译并测试了一个实例,才会有恍然大悟的感觉.下面将要讲到的一个实例是我从网上 ...

  6. ASP.NET环境下配置FCKEditor并上传图片及其它文件

    文章转自:http://blog.sina.com.cn/s/blog_568e66230100hy6a.html FCKEditor于2009年被更名为新一代的CKEditor和CKFinder,见 ...

  7. 【转】Win7环境下VS2010配置Cocos2d-x-2.1.4最新版本的开发环境(亲测)

    http://blog.csdn.net/ccf19881030/article/details/9204801 很久以前使用博客园博主子龙山人的一篇博文<Cocos2d-x win7+vs20 ...

  8. NET环境下的未处理异常(unhandled exception)的解决方案

    NET环境下的未处理异常(unhandled exception )的解决方案 .Net 框架提供了非常强大的异常处理机制,同时对一些非托管代码很难控制的系统问题比如指针越界,内存泄漏等提供了很好的解 ...

  9. VS2017环境下安装AO10.2的方法

    软件版本 Visual Studio的全称.简称及版本号对应关系为: Microsoft Visual Studio 2002 VS2002 VC7.0 Microsoft Visual Studio ...

随机推荐

  1. win7录屏工具

    psr.exe http://jingyan.baidu.com/article/aa6a2c14d330710d4d19c47c.html

  2. oledb 写入 office2010 以及发布到iis 遇到的奇怪问题总结

    这段时间在做Excel 导出升级,把之前的office2003 升级到 2010导出. 一 利用oledb 写入 Excel 2010 的时候,怎么也打不开文件,最后调查的原因是 需要修改连接字符串: ...

  3. mysql-server 的一些记录

    为避免 innodb 文件的增大.个人倾向于读立表空间.以 innodb_file_per_table=1 参数调整. 不使用默认数据目录的话,须得将 grp own 都循环设置为mysql. 昨天晚 ...

  4. [转载] TCP与UDP对比

    TCP和UDP区别     TCP UDP 是否连接 面向连接 面向非连接 传输可靠性 可靠的 不可靠的 应用场合 传输大量的数据 少量数据 速度 慢 快     OSI 和 TCP/IP 模型在传输 ...

  5. ZOJ 3872--解题报告

    题目相关: 3872相关链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5520 Edward拥有一组数列. 其定义了Be ...

  6. yii2后台上传图片,前台也能显示 的方法

    备注:::很low    高端人士 勿入  支持 吐槽  有你们的吐槽才有我的进步 还不会yii上传的  go   out    (哈哈,开玩笑)

  7. MVC&WebForm对照学习:文件上传(以图片为例)

    原文  http://www.tuicool.com/articles/myM7fe 主题 HTMLMVC模式Asp.net 博客园::首页::  ::  ::  ::管理 5 Posts :: 0 ...

  8. Spring AOP 实现功能权限校验功能

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 使用拦截器实现未登录时跳转到登录界面的功能 1 拦截器SecurityInterceptor 2spring-mvcxml拦 ...

  9. javaio-printwriter

    转自http://www.cnblogs.com/skywang12345/p/io_25.html PrintWriter 介绍 PrintWriter 是字符类型的打印输出流,它继承于Writer ...

  10. Android SDK Manager Google Apis 下载

    本意是想利用google的gcm来实装android推送功能的,很遗憾, google貌似已经停止提供啥服务给国内了,或者说国内想继续使用google 服务暂时变得几乎不可能了.找了个代理来进行goo ...