下面列举的是Klockwork告警中常见的告警形式,这些情况在编译阶段都不会报出来语法上的错误,并且在运行阶段执行到的概率很小。但是在某些场景下一旦执行到了这些语句, 很可能引起进程的跑飞和挂起。

 
1、没有对所有入参指针做有效性检查
WORD32 Test(WORD32 *p, WORD32 *q)
{
    WORD32 dwBindType = 0;
    if ((NULL == p) || (NULL == q))
    {
        SF_ASSERT(0);
        return SFWD_ERROR;
    }
    return SFWD_OK;
}
 
编程规范要求,所有入参是指针,都必须进行判空操作;如果是入参是整型等,可以根据需要决定是否对入参进行检查;但参数不合法都要做异常处理;
 
2、函数中的异常处理缺少返回值
WORD32 Test(WORD32 *p, WORD32 *q)
{
    WORD32 dwBindType = 0;
    if ((NULL == p) || (NULL == q))
    {
        SF_ASSERT(0);
        return SFWD_ERROR;        //导致与预期返回的结果不符
    }
    return SFWD_OK;
}
 
断言需要做异常处理的,并不是断言就完事了,如果tr掉,继续往下走,可能会出现跑飞或单板重启等严重问题;
在release版本,断言是被忽略的;debug版本,适当增加断言,当出现异常时,容易定位问题。
 
3、函数在异常退出前务必要释放先前申请的内存
SOCK_PKTINFO* Test(WORD32 dwReplyType)
{
    BYTE *pValidatePkt = NULL;
    SOCK_PKTINFO *pPktInfo = NULL;
 
    pValidatePkt = (BYTE *) XOS_GetUB(VER_REPLY_PKTLEN);
    if (NULL == pValidatePkt)
    {
        ROSNG_TRACE_ERROR("Error: XOS_GetUB failed!\n");
        return NULL;
    }
    MEMSET(pValidatePkt, 0, VER_REPLY_PKTLEN);
 
    if (TOPO_REPLY_OK == dwReplyType)
    {
        MEMCPY(&pValidatePkt[4], "YES", 4);
    }
    else
    {
        SF_ASSERT(0);
        XOS_RetUB(pValidatePkt);
        return NULL;
    }
    return pPktInfo;
}
 
这段代码其实有几个问题:
1.没有遵守谁申请谁释放的原则,C语言很容易出现内存泄漏,但遵守规范,这种泄漏就会少很多;
  除了申请的内存需要缓存而不是在一个消息中释放外(比如分片组包的情况),报文处理中基本上可以做到谁申请谁释放;
2.在异常流程,没有释放内存,这个是非常容易犯的错误;
3.如果是临时申请内存,应该使用PUB_GetLocalUB/PUB_RetLoacalUB这对接口;
 
 
4、函数内对空指针进行引用操作
VOID Test(SFWD_NBR_INFO *pNbrInfo)
{
    WORD32 *pIndex = NULL;
 
    if(NULL == pNbrInfo)
    {
        ROSNG_TRACE_ERROR("Error: Para is NULL!\n");
        SF_ASSERT(0);
        return;
    }
 
    if(0 == pNbrInfo->wActiveNbrNum)
    {
        pIndex = sfwd_node_new(sizeof(WORD32));
        if(NULL == pIndex)
        {
            ROSNG_TRACE_ERROR("Error: sfwd_node_new return NULL!\n");
            return;
        }
        * pIndex = pVifInfo->dwIndex;
       
    }
    XOS_RawPrint("gIndex = %d, pNbrInfo->dwNbrStatus = %d\n", * pIndex, pNbrInfo->dwNbrStatus);
    //这里如果没有执行上面if语句内的代码,就会导致对空指针进行操作;
    return;
}
 
不管是打印还是语句,只有是访问指针指向的内容,先想想这个指针有没有为空或非法地址的情况;
 
5、函数中数组操作的越界访问
WORD32 Test(SFWD_TOPO_PKT_CAP_IF_INFO_T *pIfInfo, WORD32 gIndex)
{
    WORD32 dwSubslot = 0;
    WORD32 dwSubindex = 0;
    WORD16 if_type = 0;
 
    if (NULL == pIfInfo)
    {
        ROSNG_TRACE_ERROR("sfwd_topo_pkt_cap_get_ifinfo: inParam is NULL!\n");
        SF_ASSERT(0);
        return FALSE;
    }
 
    if ((gIndex <= 0))
    {
        ROSNG_TRACE_ERROR("sfwd_topo_pkt_cap_get_ifinfo: Para error!\n");
        SF_ASSERT(0);
        return FALSE;
    }
 
    dwSubslot = gIndex / MAX_IF_NUMBER_PERCARD;
    dwSubindex = gIndex % MAX_IF_NUMBER_PERCARD;
    if((dwSubslot >= MAX_SUBCARD_NUMBER) || (dwSubindex > MAX_IF_NUMBER_PERCARD))  
    {
        ROSNG_TRACE_WARNING("sfwd_topo_pkt_cap_get_ifinfo: invalid subslot or subindex.\n");
        SF_ASSERT(0);
        return FALSE;
    }
    if_type = gInterface[dwSubslot][dwSubindex].wType;
    //在对gInterface数组进行访问时,如果dwSubslot、dwSubindex的下标值超出了该数组声明的大小可能产生越界。所以,需要根据代码的上下文来对数组的下标做有效性检查(并不是所有的数组访问都检查,有些是没必要的)
 
    return TRUE;
}
 
#define SFWD_SUBCARD_NO_CHECK(A, B)    ((A >= MAX_SUBCARD_NUMBER) || (B > MAX_IF_NUMBER_PERCARD))
 
数组越界也是经常犯的错误,对数组的访问,加一下检查;考虑到会频繁出现数组下标的检查,可以写一个类似上面的宏;

Klockwork告警常见错误的更多相关文章

  1. 初识JAVA(二)(送给Java和安卓初学者)----常见错误

    博主接着上篇的来讲哦,以后的更新中,博主会出一些练习题,有兴趣的可以做做然后吧代码粘贴到下面,大家可以一起研究学习,一起进步,本篇文章主要讲的是: 一.常见错误 二.连接上篇一起的训练 无论是什么方向 ...

  2. ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock

    ubuntu 常见错误--Could not get lock /var/lib/dpkg/lock 通过终端安装程序sudo apt-get install xxx时出错:E: Could not ...

  3. coreseek常见错误原因及解决方法

    coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和 ...

  4. Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误

    嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 ge ...

  5. C语言初学者代码中的常见错误与瑕疵(23)

    见:C语言初学者代码中的常见错误与瑕疵(23)

  6. struts2.5框架使用通配符指定方法常见错误

    struts2.5框架使用通配符指定方法(常见错误) 在学习struts框架时经常会使用到通配符调用方法,如下: <package name="shop" namespace ...

  7. .Net常见错误

    常见错误 #1: 把引用当做值来用,或者反过来 C++ 和其他很多语言的程序员,习惯了给变量赋值的时候,要么赋单纯的值,要么是现有对象的引用.然而,在C# 中,是值还是引用,是由写这个对象的程序员决定 ...

  8. WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭

    在我们开发WCF项目的时候,常常会碰到一些莫名其妙的错误,有时候如果根据它的错误提示信息,一般很难定位到具体的问题所在,而由于WCF服务的特殊性,调试起来也不是那么方便,因此往往会花费不少时间来进行跟 ...

  9. Python程序的常见错误(收集篇)

    关于Python Python是一门解释性的,面向对象的,并具有动态语义的高级编程语言.它高级的内置数据结构,结合其动态类型和动态绑定的特性,使得它在快速应用程序开发(Rapid Applicatio ...

随机推荐

  1. mysql 千分位 Format

    原文:mysql 千分位 Format select Format(123456789) 结果:123,456,789

  2. 使用Vs2005打造简单分页浏览器(1)原创

    原文:使用Vs2005打造简单分页浏览器(1)原创 使用Vs2005打造简单分页浏览器(1)原创1引言2功能3实现过程以及关键点4总结5不足之处6其他7 代码下载 1    引言很早就有搞一个浏览器的 ...

  3. GetDirectories 出错的解决方法

    我想找到D盘里面所有 "*.pst文件,类似 windows 下的磁盘搜索功能, using System.IO; Directory.GetFiles(@"d:\", ...

  4. oracle 电子商务解决方案讲义

    1. 电商营销(CRM) - 高端客户体验 2. 当当网李国庆做 "千千面"购物体验 3. 所使用的唯一的产品oracle的CRM 4. 个人的事情.谁在世界上是用户体验. 5. ...

  5. C#中如何获取系统环境变量

    原文:C#中如何获取系统环境变量 C#中获取系统环境变量需要用到Environment Class.其中提供了有关当前环境和平台的信息以及操作它们的方法.该类不能被继承. 以下代码得到%systemd ...

  6. [Elasticsearch] 邻近匹配 (一) - 短语匹配以及slop參数

    本文翻译自Elasticsearch官方指南的Proximity Matching一章. 邻近匹配(Proximity Matching) 使用了TF/IDF的标准全文搜索将文档,或者至少文档中的每一 ...

  7. PHP 调用asp.net Web Services服务问题总结

    原文:PHP 调用asp.net Web Services服务问题总结 PHP是弱类型语言,转换非常不方便. < ?php //soap 客户端 $client=new SoapClient(' ...

  8. PDF解决方案(1)--文件上传

    相关专题链接 PDF解决方案(1)--文件上传 PDF解决方案(2)--文件转PDF PDF解决方案(3)--PDF转SWF PDF解决方案(4)--在线浏览 前言:最近参与了一个项目,客户要求把系统 ...

  9. TodoList开发笔记 – PartⅠ

    做了一年多的桌面软件,最近开始转向Web方面的开发,既然比较熟悉Net那么首当其冲就是学习ASP.Net,以及HTML.CSS.Javascript. 为了检验这个把星期来的学习成果,着手做了一个To ...

  10. idea中output log4j中文乱码

    1.设置tomcat中的VM optins:-Dfile.encofing=UTF-8 2.idea安装目录bin文件夹中idea.exe.vmoptions.idea64.exe.vmoptions ...