实战开发经验: 软件中的错误收集策略

Error = 0 的程序是不存在的,怎样收集和处理程序中的错误?怎样更好地利用错误信息的收集和反馈来协助程序的调试?怎样让产品发布后,用户能够反馈出更有价值的问题信息?这些问题是本文将要涉及的,最近对自己所做项目中的错误处理机制做了一些总结与思考,故在此讨论,希望对大家有所帮助。


目前,按照我个人的理解,软件中的错误收集和反馈方式主要有如下几种:


第一种方式:使用常用的信息输出语句。

    

对于控制台程序,可以使用 printf 语句或者 std::cout 将错误信息打印出来;对于MFC程序,可以使用 TRACE 宏,将错误信息输出到 output 窗口,或者使用 MessageBox直接弹出对话框将错误信息告知用户 。

    

这些处理策略往往针对于“交互性”的代码段,可以实现 实时反馈错误信息,以供用户实时地进行处理,以免后面产生更大的错误。


第二种方式:使用错误日志方式

    

思想:将程序中的所有错误信息输出到错误日志文件中,这样有以下这些好处:

    

1. 当程序发布后,客户在使用中遇到问题后,可以直接将错误日志发送给程序员,将极大地方便了问题的定位及原因的分析。

    

2. 便于调试多线程或者涉及网络通信等复杂的程序,因为在这样的程序中,设置断点的调试方式非常地不方便,一旦暂停在断点处,往往为引起线程异常或者 网络连接断开等问题,极大影响了调试的效率。如果将错误信息打印到文件中,错误描述详细丰富一些,可以极大地提高调试的效率。

    

3. 便于程序进行大规模的性能测试。例如:C/S模式的系统,进行100个客户端对服务器的访问测试,使用这种错误收集策略可以方便地通过分析错误日志文件来推测系统的性能。

    

下面思考这样一个问题:很多软件的设计上都有一个类似TCP/IP协议的应用层的模块,该模块一般是直接与客户端交互的一层,它隔离了核心代码模块与客户端的耦合,那么,对于这样一种层次结构比较深设计方案,最底层发生的错误信息怎样传递到最上层?每一层都提供获取错误信息的接口?这样开销太大,也往往不够理想,那该怎样处理呢?

    

我想应该主要有以下两种处理策略,也就是我即将引出的错误收集和反馈的第三种和第四种策略:


第三种方式:异常机制

    

这里说说C++的异常处理机制,它是一个用来有效地处理运行错误的非常强大且灵活的工具,它提供了更多的弹性、安全性和稳固性,克服了传统方法所带来的问题.

    

异常的抛出和处理主要使用了以下三个关键字: try、 throw 、 catch 。

    

抛出异常、捕获异常 ,这些是C++提供的极其方便地处理异常策略,可以实现在最底层抛出异常,由最上层捕获,并且处理。

    

说实话,C++异常机制的确是一种处理错误和异常的很好的策略,如果需要使用该机制,需要从软件架构和设计时就要开始考虑,一旦软件结构和代码写到一定程度后,再引入异常机制将很难达到很好的效果。其实,要想用好c++异常机制,不是一件很容易的事,特别是对于项目组里面有大量新人的时候,故使用成本还是挺高的。

    

关于C++异常机制很多C++书籍都有介绍,我也不在此赘述,本博客也有一篇C++异常机制的入门示例代码,有兴趣可以看看: http://ticktick.blog.51cto.com/823160/191881


第四种方式:GetLastError模式

    

经常开发windows程序的人应该都了解,windows程序有一个API:GetLastError,它其实代表着一种错误收集处理机制。 

    

当一个Windows函数检测到一个错误时,它会使用一个称为线程本地存储器(thread-localstorage)的机制。当函数返回时,它的返回值为flase就能指明一个错误已经发生。若要确定这是个什么错误,可以调用GetLastError函数来获取:该函数只返回线程的32位错误代码。

    

WinError.h头文件包含了Microsoft公司定义的错误代码的列表。

    

当Windows函数运行失败时,应该立即调用GetLastError函数。如果调用另一个Windows函数,它的值很可能被改写。

    

Visual studio还配有一个小的实用程序,称为Error Lookup.

    

如果在编写的应用程序中发现一个错误,可能想要向用户显示该错误的文本描述。Windows提供了一个函数,可以将错误代码转换成它的文本描述。该函数称为FormatMessage。

    

以上就是GetLastError模式的介绍,可以简单地把它想象成为这样一种模式:有一个全局的变量,可以用来存放32位错误代码,一旦Windows函数运行失败,就将错误代码赋值给这个全局的变量,每当调用GetLastError,则将该错误代码返回出来以供外部分析原因。

    

其实,我们自己也可以实现这样一个GetLastError模式的错误收集机制,收集整个程序中最新的错误信息,供上层及时调用查询,定义自己的错误代码和错误描述信息串,那么,怎样才能更好地实现属于自己的类似的错误收集反馈机制呢?怎样使它具有更好地移植性、健壮性(支持多线程等)和易扩展性(加入新的错误代码和信息)呢?我将在后面的文章中介绍我的思考和设计。



本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/213580,如需转载请自行联系原作者
上一篇:Solr的搭建


下一篇:Spring Cloud Alibaba 七天训练营(六)分布式消息(事件)驱动