zoukankan      html  css  js  c++  java
  • Klockwork告警常见错误

    下面列举的是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! ");
            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! ");
            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! ");
                return;
            }
            * pIndex = pVifInfo->dwIndex;
           
        }
        XOS_RawPrint("gIndex = %d, pNbrInfo->dwNbrStatus = %d ", * 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! ");
            SF_ASSERT(0);
            return FALSE;
        }
     
        if ((gIndex <= 0))
        {
            ROSNG_TRACE_ERROR("sfwd_topo_pkt_cap_get_ifinfo: Para error! ");
            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. ");
            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))
     
    数组越界也是经常犯的错误,对数组的访问,加一下检查;考虑到会频繁出现数组下标的检查,可以写一个类似上面的宏;
  • 相关阅读:
    class 关键字
    自适应Web主页
    前端跨域解决
    HTML5新增特性
    HTTP知识点【总结篇】
    针对Web应用的【攻击模式篇】
    HTTPS和HTTP
    HTTP状态码之【整理篇】
    SpringCloud配制eureka
    maven连接国内仓库
  • 原文地址:https://www.cnblogs.com/wanghaoran/p/3690879.html
Copyright © 2011-2022 走看看